Lots of assembler and rule bugfixing.
authorDavid Given <dg@cowlark.com>
Tue, 4 Sep 2018 21:43:24 +0000 (23:43 +0200)
committerDavid Given <dg@cowlark.com>
Tue, 4 Sep 2018 21:43:24 +0000 (23:43 +0200)
mach/mips/as/instructions.dat
mach/mips/as/mach2.c
mach/mips/as/mach3.c
mach/mips/as/mach4.c
mach/mips/as/mktables.lua
mach/mips/mcg/table

index 80af89f..0d6b909 100644 (file)
 # or RD, RS, zero
 000000<RS->00000<RD->00000100101 "mov" RD=gpr ',' RS=gpr
 
+# Condition code tokens; these have to be defined here because .f overlaps with
+# a format code.
+
+%token .f
+%token .un
+%token .eq
+%token .ueq
+%token .olt
+%token .ult
+%token .ole
+%token .ule
+%token .sf
+%token .ngle
+%token .seq
+%token .ngl
+%token .lt
+%token .nge
+%token .le
+%token .ngt
+
 # Core ALU instructions.
 
 000000<RS-><RT-><RD->00000100000 "add" RD=gpr ',' RS=gpr ',' RT=gpr
 00000000000000000000000000000000 "nop"
 000000<RS-><RT-><RD->00000100111 "nor" RD=gpr ',' RS=gpr ',' RT=gpr
 000000<RS-><RT-><RD->00000100101 "or" RD=gpr ',' RS=gpr ',' RT=gpr
-001101<RS-><RT-><IMM-----------> "ori" RS=gpr ',' RT=gpr
+001101<RS-><RT-><IMM-----------> "ori" RS=gpr ',' RT=gpr ',' IMM=e16
 00000000000000000000000101000000 "pause"
 110011<RS-><H--><IMM-----------> "pref" H=u5 ',' IMM=e16 '(' RS=gpr ')'
 011111<RS-><H--><IMM---->0100011 "prefe" H=u5 ',' IMM=e9 '(' RS=gpr ')'
 
 # FPU instructions.
 
-010001<F-->00000<FS-><FD->000101 "abs." F=FMT FD=fpr ',' FS=fpr
-010001<F--><FT-><FS-><FD->000000 "add." F=FMT FD=fpr ',' FS=fpr ',' FT=fpr
-010011<RS-><FT-><FS-><FD->011110 "alnv.ps" FD=fpr ',' FS=fpr ',' FT=fpr ',' RS=gpr
-010001<F--><FT-><FS-><C>0011<CO> "c." CO=FCOND '.' F=FMT FS=fpr ',' FT=fpr
-010001<F-->00000<FS-><FD->001010 "ceil.l." F=FMT FD=fpr ',' FS=fpr
-010001<F-->00000<FS-><FD->001110 "ceil.w." F=FMT FD=fpr ',' FS=fpr
+010001<F-->00000<FS-><FD->000101 "abs" F=fmt FD=fpr ',' FS=fpr
+010001<F--><FT-><FS-><FD->000000 "add" F=fmt FD=fpr ',' FS=fpr ',' FT=fpr
+010011<RS-><FT-><FS-><FD->011110 "alnv" ".ps" FD=fpr ',' FS=fpr ',' FT=fpr ',' RS=gpr
+010001<F-->00000<FS-><FD->001010 "ceil" ".l" F=fmt FD=fpr ',' FS=fpr
+010001<F-->00000<FS-><FD->001110 "ceil" ".w" F=fmt FD=fpr ',' FS=fpr
 01000100010<RT-><FS->00000000000 "cfc1" RT=gpr ',' FS=fpr
 01000100110<RT-><FS->00000000000 "ctc1" RT=gpr ',' FS=fpr
-010001<F-->00000<FS-><FD->100001 "cvt.d." F=FMT FD=fpr ',' FS=fpr
-010001<F-->00000<FS-><FD->100101 "cvt.l." F=FMT FD=fpr ',' FS=fpr
-01000110000<FT-><FS-><FD->100110 "cvt.ps.s" FD=fpr ',' FS=fpr ',' FT=fpr
-010001<F-->00000<FS-><FD->100000 "cvt.s." F=FMT FD=fpr ',' FS=fpr
-0100011011000000<FS-><FD->101000 "cvt.s.pl" FS=fpr ',' FD=fpr
-0100011011000000<FS-><FD->100000 "cvt.s.pu" FS=fpr ',' FD=fpr
-010001<F-->00000<FS-><FD->100100 "cvt.w." F=FMT FD=fpr ',' FS=fpr
-010001<F--><FT-><FS-><FD->000011 "div." F=FMT FD=fpr ',' FS=fpr ',' FT=fpr
-010001<F-->00000<FS-><FD->001011 "floor.l." F=FMT FD=fpr ',' FS=fpr
-010001<F-->00000<FS-><FD->001111 "floor.w." F=FMT FD=fpr ',' FS=fpr
+010001<F-->00000<FS-><FD->100001 "cvt" ".d" F=fmt FD=fpr ',' FS=fpr
+010001<F-->00000<FS-><FD->100101 "cvt" ".l" F=fmt FD=fpr ',' FS=fpr
+01000110000<FT-><FS-><FD->100110 "cvt" ".ps" ".s" FD=fpr ',' FS=fpr ',' FT=fpr
+010001<F-->00000<FS-><FD->100000 "cvt" ".s" F=fmt FD=fpr ',' FS=fpr
+0100011011000000<FS-><FD->101000 "cvt" ".s" ".pl" FS=fpr ',' FD=fpr
+0100011011000000<FS-><FD->100000 "cvt" ".s" ".pu" FS=fpr ',' FD=fpr
+010001<F-->00000<FS-><FD->100100 "cvt" ".w" F=fmt FD=fpr ',' FS=fpr
+010001<F--><FT-><FS-><FD->000011 "div" F=fmt FD=fpr ',' FS=fpr ',' FT=fpr
+010001<F-->00000<FS-><FD->001011 "floor" ".l" F=fmt FD=fpr ',' FS=fpr
+010001<F-->00000<FS-><FD->001111 "floor" ".w" F=fmt FD=fpr ',' FS=fpr
 110101<RS-><FT-><IMM-----------> "ldc1" FT=fpr ',' IMM=e16 '(' RS=gpr ')'
 010011<RS-><RT->00000<FD->000001 "ldxc1" FD=fpr ',' RT=gpr '(' RS=gpr ')'
 010011<RS-><RT->00000<FD->000101 "luxc1" FD=fpr ',' RT=gpr '(' RS=gpr ')'
 110001<RS-><FT-><IMM-----------> "lwc1" FT=fpr ',' IMM=e16 '(' RS=gpr ')'
 010011<RS-><RT->00000<FD->000000 "lwxc1" FD=fpr ',' RT=gpr '(' RS=gpr ')'
-010011<FR-><FT-><FS-><FD->100<F> "madd." F=FMT3 FD=fpr ',' FR=fpr ',' FS=fpr ',' FT=fpr
+010011<FR-><FT-><FS-><FD->100<F> "madd" F=fmt3 FD=fpr ',' FR=fpr ',' FS=fpr ',' FT=fpr
 01000100000<RT-><FS->00000000000 "mfc1" RT=gpr ',' FS=fpr
 01000100011<RT-><FS->00000000000 "mfhc1" RT=gpr ',' FS=fpr
-010001<F-->00000<FS-><FD->000110 "mov." F=FMT FD=fpr ',' FS=fpr
-000000<RS-><C>00<RD->00000000001 "movf" RD=gpr ',' RS=gpr ',' C=FCOND
-010001<F--><C>00<FS-><FD->010001 "movf." F=FMT FD=fpr ',' FS=fpr ',' C=FCOND
-010001<F--><RT-><FS-><FD->010011 "movn." F=FMT FD=fpr ',' FS=fpr ',' RT=gpr
-000000<RS-><C>01<RD->00000000001 "movt" RD=gpr ',' RS=gpr ',' C=FCOND
-010001<F--><C>01<FS-><FD->010001 "movt." F=FMT FD=fpr ',' FS=fpr ',' C=FCOND
-010001<F--><RT-><FS-><FD->010010 "movz." F=FMT FD=fpr ',' FS=fpr ',' RT=gpr
-010011<FR-><FT-><FS-><FD->101<F> "msub." F=FMT3 FD=fpr ',' FR=fpr ',' FS=fpr ',' FT=fpr
+010001<F-->00000<FS-><FD->000110 "mov" F=fmt FD=fpr ',' FS=fpr
+000000<RS-><C>00<RD->00000000001 "movf" RD=gpr ',' RS=gpr ',' C=u3
+010001<F--><C>00<FS-><FD->010001 "movf" F=fmt FD=fpr ',' FS=fpr ',' C=u3
+010001<F--><RT-><FS-><FD->010011 "movn" F=fmt FD=fpr ',' FS=fpr ',' RT=gpr
+000000<RS-><C>01<RD->00000000001 "movt" RD=gpr ',' RS=gpr ',' C=u3
+010001<F--><C>01<FS-><FD->010001 "movt" F=fmt FD=fpr ',' FS=fpr ',' C=u3
+010001<F--><RT-><FS-><FD->010010 "movz" F=fmt FD=fpr ',' FS=fpr ',' RT=gpr
+010011<FR-><FT-><FS-><FD->101<F> "msub" F=fmt3 FD=fpr ',' FR=fpr ',' FS=fpr ',' FT=fpr
 01000100100<RT-><FS->00000000000 "mtc1" RT=gpr ',' FS=fpr
 01000100111<RT-><FS->00000000000 "mthc1" RT=gpr ',' FS=fpr
-010001<F--><FT-><FS-><FD->000010 "mul." F=FMT FD=fpr ',' FS=fpr ',' FT=fpr
-010001<F-->00000<FS-><FD->000111 "neg." F=FMT FD=fpr ',' FS=fpr
-010011<FR-><FT-><FS-><FD->110<F> "nmadd." F=FMT3 FD=fpr ',' FR=fpr ',' FS=fpr ',' FT=fpr
-010011<FR-><FT-><FS-><FD->111<F> "nmsub." F=FMT3 FD=fpr ',' FR=fpr ',' FS=fpr ',' FT=fpr
-01000110110<FT-><FS-><FD->101100 "pll.ps" FD=fpr ',' FS=fpr ',' FT=fpr
-01000110110<FT-><FS-><FD->101101 "plu.ps" FD=fpr ',' FS=fpr ',' FT=fpr
-01000110110<FT-><FS-><FD->101110 "pul.ps" FD=fpr ',' FS=fpr ',' FT=fpr
-01000110110<FT-><FS-><FD->101111 "puu.ps" FD=fpr ',' FS=fpr ',' FT=fpr
-010001<F-->00000<FS-><FD->010101 "recip." F=FMT FD=fpr ',' FS=fpr
-010001<F-->00000<FS-><FD->001000 "round.l." F=FMT FD=fpr ',' FS=fpr
-010001<F-->00000<FS-><FD->001100 "round.w." F=FMT FD=fpr ',' FS=fpr
-010001<F-->00000<FS-><FD->010110 "rsqrt." F=FMT FD=fpr ',' FS=fpr
+010001<F--><FT-><FS-><FD->000010 "mul" F=fmt FD=fpr ',' FS=fpr ',' FT=fpr
+010001<F-->00000<FS-><FD->000111 "neg" F=fmt FD=fpr ',' FS=fpr
+010011<FR-><FT-><FS-><FD->110<F> "nmadd" F=fmt3 FD=fpr ',' FR=fpr ',' FS=fpr ',' FT=fpr
+010011<FR-><FT-><FS-><FD->111<F> "nmsub" F=fmt3 FD=fpr ',' FR=fpr ',' FS=fpr ',' FT=fpr
+01000110110<FT-><FS-><FD->101100 "pll" ".ps" FD=fpr ',' FS=fpr ',' FT=fpr
+01000110110<FT-><FS-><FD->101101 "plu" ".ps" FD=fpr ',' FS=fpr ',' FT=fpr
+01000110110<FT-><FS-><FD->101110 "pul" ".ps" FD=fpr ',' FS=fpr ',' FT=fpr
+01000110110<FT-><FS-><FD->101111 "puu" ".ps" FD=fpr ',' FS=fpr ',' FT=fpr
+010001<F-->00000<FS-><FD->010101 "recip." F=fmt FD=fpr ',' FS=fpr
+010001<F-->00000<FS-><FD->001000 "round" ".l" F=fmt FD=fpr ',' FS=fpr
+010001<F-->00000<FS-><FD->001100 "round" ".w" F=fmt FD=fpr ',' FS=fpr
+010001<F-->00000<FS-><FD->010110 "rsqrt" F=fmt FD=fpr ',' FS=fpr
 111101<RS-><FT-><IMM-----------> "sdc1" FT=fpr ',' IMM=e16 '(' RS=gpr ')'
 010011<RS-><RT->00000<FD->001001 "sdxc1" FD=fpr ',' RT=gpr '(' RS=gpr ')'
-010001<F-->00000<FS-><FD->000100 "sqrt." F=FMT FD=fpr ',' FS=fpr
-010001<F--><FT-><FS-><FD->000001 "sub." F=FMT FD=fpr ',' FS=fpr ',' FT=fpr
+010001<F-->00000<FS-><FD->000100 "sqrt" F=fmt FD=fpr ',' FS=fpr
+010001<F--><FT-><FS-><FD->000001 "sub" F=fmt FD=fpr ',' FS=fpr ',' FT=fpr
 010011<RS-><RT->00000<FD->001101 "suxc1" FD=fpr ',' RT=gpr '(' RS=gpr ')'
 111001<RS-><FT-><IMM-----------> "swc1" FT=fpr ',' IMM=e16 '(' RS=gpr ')'
 010011<RS-><RT->00000<FD->001000 "swxc1" FD=fpr ',' RT=gpr '(' RS=gpr ')'
 
 # Generic coprocessor instructions.
 
+010001<F--><FT-><FS-><C>0011<CO> "c" CO=fcond F=fmt C=u3 ',' FS=fpr ',' FT=fpr
 01000101000<C>00<OFF-----------> "bc1f" C=u3 ',' OFF=offset16
 0100010100000000<OFF-----------> "bc1f" OFF=offset16
 01000101000<C>10<OFF-----------> "bc1fl" C=u3 ',' OFF=offset16
index db6a311..9c81ed9 100644 (file)
@@ -1,7 +1,5 @@
 %token <y_word> GPR
 %token <y_word> FPR
-%token <y_word> FMT
-%token <y_word> FMT3
 %token <y_word> FCOND
 
 %token <y_word> OP_LI
@@ -12,6 +10,9 @@
 %type <y_word> u25 u20 u16 u5 u3
 %type <y_word> abs26 offset16
 
+%type <y_word> fmt fmt3
+%type <y_word> fcond
+
 %type <y_word> extmsblsb insmsblsb
 
 #include "definitions.y"
index 4e346d7..d75845e 100644 (file)
 0,     FPR,        30,         "f30",
 0,     FPR,        31,         "f31",
 
-/* Floating-point comparison values */
-
-0,     FCOND,      0,          "f",
-0,     FCOND,      1,          "un",
-0,     FCOND,      2,          "eq",
-0,     FCOND,      3,          "ueq",
-0,     FCOND,      4,          "olt",
-0,     FCOND,      5,          "ult",
-0,     FCOND,      6,          "ole",
-0,     FCOND,      7,          "ule",
-0,     FCOND,      8,          "sf",
-0,     FCOND,      9,          "ngle",
-0,     FCOND,      10,         "seq",
-0,     FCOND,      11,         "ngl",
-0,     FCOND,      12,         "lt",
-0,     FCOND,      13,         "nge",
-0,     FCOND,      14,         "le",
-0,     FCOND,      15,         "ngt",
-
-0,     FMT,        16,         "s",
-0,     FMT,        17,         "d",
-0,     FMT,        20,         "w",
-0,     FMT,        21,         "l",
-0,     FMT,        22,         "ps",
-
-0,     FMT3,       0,          "s",
-0,     FMT3,       1,          "d",
-0,     FMT3,       4,          "w",
-0,     FMT3,       5,          "l",
-0,     FMT3,       6,          "ps",
-
 0,     OP_LI,      0,          "li",
 0,     OP_LA,      0,          "la",
 
index 3cce17e..fddeb25 100644 (file)
 gpr: GPR
 fpr: FPR
 
+fmt3
+       : OP__DOT_S  { $$ = 0; }
+       | OP__DOT_D  { $$ = 1; }
+       | OP__DOT_W  { $$ = 4; }
+       | OP__DOT_L  { $$ = 5; }
+       | OP__DOT_PS { $$ = 6; }
+fmt: fmt3        { $$ = $1 + 16; }
+
+fcond
+       : OP__DOT_F    { $$ = 0; }
+       | OP__DOT_UN   { $$ = 1; }
+       | OP__DOT_EQ   { $$ = 2; }
+       | OP__DOT_UEQ  { $$ = 3; }
+       | OP__DOT_OLT  { $$ = 4; }
+       | OP__DOT_ULT  { $$ = 5; }
+       | OP__DOT_OLE  { $$ = 6; }
+       | OP__DOT_ULE  { $$ = 7; }
+       | OP__DOT_SF   { $$ = 8; }
+       | OP__DOT_NGLE { $$ = 9; }
+       | OP__DOT_SEQ  { $$ = 10; }
+       | OP__DOT_NGL  { $$ = 11; }
+       | OP__DOT_LT   { $$ = 12; }
+       | OP__DOT_NGE  { $$ = 13; }
+       | OP__DOT_LE   { $$ = 14; }
+       | OP__DOT_NGT  { $$ = 15; }
+
 e16
        : absexp
        {
index cb8565f..f1214e2 100755 (executable)
@@ -1,17 +1,19 @@
 local args = {...}
 
-local wordscount = 0
 local words = {}
 local insns = {}
 
 local function addword(word)
-       local n = words[word]
-       if not n then
-               words[word] = wordscount
-               wordscount = wordscount + 1
-               n = wordscount
+       local w = words[word]
+       if not w then
+               w = word:upper()
+               w = w:gsub("%.", "_DOT_")
+       if not w:match("^[A-Z0-9_]*$") then
+                       error(word.." is not a valid token")
+        end
+               words[word] = w
        end
-       return n
+       return w
 end
 
 local function parsesyntax(line)
@@ -125,7 +127,9 @@ while true do
        end
        line = line:gsub("#.*$", "")
        line = line:gsub(" *$", "")
-       if line ~= "" then
+       if line:find("^%%token ") then
+               addword(line:sub(8))
+       elseif line ~= "" then
                local fields = parsefields(line)
                local syntax = parsesyntax(line:sub(34, #line))
        insns[#insns+1] = {
@@ -143,7 +147,7 @@ definitionsfp:close()
 
 local tokensfp = io.open(args[2], "w")
 for word, value in pairs(words) do
-       tokensfp:write("0, OP_", tostring(value), ", 0, \"", word, "\",\n")
+       tokensfp:write("0, OP_", value, ", 0, \"", word, "\",\n")
 end
 tokensfp:close()
 
@@ -157,7 +161,7 @@ for index, insn in ipairs(insns) do
        end
        for _, word in ipairs(insn.syntax) do
                if word.word then
-                       rulesfp:write(" OP_", tostring(word.word))
+                       rulesfp:write(" OP_", word.word)
                end
                if word.punct then
                        rulesfp:write(" ", word.punct)
index fc69ba7..054a39b 100644 (file)
@@ -434,62 +434,26 @@ PATTERNS
         emit "nop"
         cost 8;
 
-       CJUMPEQ(COMPARESI.I(left:(int)reg, right:(int)reg), PAIR(true:BLOCK.I, false:BLOCK.I))
-        emit "beq %left, %right, $true"
+       CJUMPEQ(left:(int)reg, PAIR(true:BLOCK.I, false:BLOCK.I))
+        emit "beq %left, zero, $true"
         emit "nop"
         emit "b $false"
         emit "nop"
         cost 16;
 
-       CJUMPLT(COMPARESI.I(left:(int)reg, right:(int)reg), PAIR(true:BLOCK.I, false:BLOCK.I))
-        emit "slt at, %left, %right"
-        emit "bne at, zero, $true"
-        emit "nop"
-        emit "b $false"
-        emit "nop"
-        cost 20;
-
-       CJUMPLT(COMPAREUI.I(left:(int)reg, right:(int)reg), PAIR(true:BLOCK.I, false:BLOCK.I))
-        emit "sltu at, %left, %right"
-        emit "bne at, zero, $true"
-        emit "nop"
-        emit "b $false"
-        emit "nop"
-        cost 20;
-
-       CJUMPLT(COMPARESI.I(left:(int)reg, right:CONST.I), PAIR(true:BLOCK.I, false:BLOCK.I))
-        when specific_constant(%right, 0)
+       CJUMPLT(left:(int)reg, PAIR(true:BLOCK.I, false:BLOCK.I))
         emit "bltz %left, $true"
         emit "nop"
         emit "b $false"
         emit "nop"
-        cost 16;
-
-       CJUMPLE(COMPARESI.I(left:(int)reg, right:(int)reg), PAIR(true:BLOCK.I, false:BLOCK.I))
-        emit "sle at, %left, %right"
-        emit "bne at, zero, $true"
-        emit "nop"
-        emit "b $false"
-        emit "nop"
-        cost 20;
-
-       CJUMPLE(COMPAREUI.I(left:(int)reg, right:(int)reg), PAIR(true:BLOCK.I, false:BLOCK.I))
-        emit "sleu at, %left, %right"
-        emit "bne at, zero, $true"
-        emit "nop"
-        emit "b $false"
-        emit "nop"
         cost 20;
 
-       CJUMPLE(COMPARESI.I(left:(int)reg, right:CONST.I), PAIR(true:BLOCK.I, false:BLOCK.I))
-        when specific_constant(%right, 0)
+       CJUMPLE(left:(int)reg, PAIR(true:BLOCK.I, false:BLOCK.I))
         emit "blez %left, $true"
         emit "nop"
         emit "b $false"
         emit "nop"
-        cost 16;
-
-    COMPAREUI.I(left:(int)reg, right:(int)reg);
+        cost 20;
 
     #define CALLLABEL(insn) \
         insn (dest:LABEL.I) \
@@ -553,17 +517,17 @@ PATTERNS
 
        /* If 0 then 1, else 0 */
        out:(int)reg = IFEQ.I(in:(int)reg)
-               emit "sleu %out, %in, zero"
+               emit "sltiu %out, %in, 1"
                cost 4;
 
        /* If -1 then 1, else 0 */
        out:(int)reg = IFLT.I(in:(int)reg)
-               emit "slt %out, %in, zero"
+               emit "srl %out, %in, 31"
                cost 4;
 
        /* If 1 or 0 then 1, else 0 */
        out:(int)reg = IFLE.I(in:(int)reg)
-               emit "sle %out, %in, zero"
+               emit "slt %out, %in, 1"
                cost 4;
 
 
@@ -620,6 +584,16 @@ PATTERNS
                emit "addiu %out, %left, -[$right]"
                cost 4;
 
+       out:(int)reg = DIV.I(left:(int)reg, right:(int)reg)
+               emit "div %left, %right"
+               emit "mflo %out"
+               cost 8;
+
+       out:(int)reg = DIVU.I(left:(int)reg, right:(int)reg)
+               emit "divu %left, %right"
+               emit "mflo %out"
+               cost 8;
+
        out:(int)reg = MOD.I(left:(int)reg, right:(int)reg)
                emit "div %left, %right"
                emit "mfhi %out"
@@ -632,9 +606,6 @@ PATTERNS
 
     ALUR(MUL.I, "mul")
 
-    ALUR(DIV.I, "divw")
-    ALUR(DIVU.I, "divwu")
-
     ALUR(ASL.I, "sllv")
     ALUC(ASL.I, "sll")
     ALUR(ASR.I, "srav")
@@ -697,10 +668,20 @@ PATTERNS
                cost 4;
 
        out:(double)reg = FROMSI.D(in:(int)reg)
-               emit "mtc1 %out, %in"
+               emit "mtc1 %in, %out" /* mtc1 has reversed parameters */
                emit "cvt.d.w %out, %out"
                cost 4;
 
+       out:(int)reg = FROMSD.I(in:(double)reg)
+        emit "trunc.w.d f31, %in"
+        emit "mfc1 %out, f31"
+        cost 8;
+
+    out:(double)reg = COPYL.D(in:(long)reg)
+        emit "mtc1 %in.0, %out" /* mtc1 has reversed parameters */
+        emit "mthic1 %in.1, %out" /* mtc1 has reversed parameters */
+        cost 8;
+
        /* Floats */
 
        out:(float)reg = ADDF.F(left:(float)reg, right:(float)reg)
@@ -720,9 +701,14 @@ PATTERNS
                cost 4;
 
        out:(float)reg = FROMSI.F(in:(int)reg)
-               emit "mtc1 %out, %in"
+               emit "mtc1 %in, %out" /* mtc1 has reversed parameters */
                emit "cvt.s.w %out, %out"
                cost 4;
 
+       out:(int)reg = FROMSF.I(in:(double)reg)
+        emit "trunc.w.s f31, %in"
+        emit "mfc1 %out, f31"
+        cost 8;
+
 /* vim: set sw=4 ts=4 expandtab : */