From 9d80756253cc0b218e83a98c93e49f514db77409 Mon Sep 17 00:00:00 2001 From: David Given Date: Tue, 4 Sep 2018 23:43:24 +0200 Subject: [PATCH] Lots of assembler and rule bugfixing. --- mach/mips/as/instructions.dat | 100 ++++++++++++++++++++-------------- mach/mips/as/mach2.c | 5 +- mach/mips/as/mach3.c | 31 ----------- mach/mips/as/mach4.c | 26 +++++++++ mach/mips/as/mktables.lua | 24 ++++---- mach/mips/mcg/table | 84 ++++++++++++---------------- 6 files changed, 138 insertions(+), 132 deletions(-) diff --git a/mach/mips/as/instructions.dat b/mach/mips/as/instructions.dat index 80af89fdc..0d6b90909 100644 --- a/mach/mips/as/instructions.dat +++ b/mach/mips/as/instructions.dat @@ -12,6 +12,26 @@ # or RD, RS, zero 0000000000000000100101 "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. 00000000000100000 "add" RD=gpr ',' RS=gpr ',' RT=gpr @@ -94,7 +114,7 @@ 00000000000000000000000000000000 "nop" 00000000000100111 "nor" RD=gpr ',' RS=gpr ',' RT=gpr 00000000000100101 "or" RD=gpr ',' RS=gpr ',' RT=gpr -001101 "ori" RS=gpr ',' RT=gpr +001101 "ori" RS=gpr ',' RT=gpr ',' IMM=e16 00000000000000000000000101000000 "pause" 110011 "pref" H=u5 ',' IMM=e16 '(' RS=gpr ')' 0111110100011 "prefe" H=u5 ',' IMM=e9 '(' RS=gpr ')' @@ -159,64 +179,64 @@ # FPU instructions. -01000100000000101 "abs." F=FMT FD=fpr ',' FS=fpr -010001000000 "add." F=FMT FD=fpr ',' FS=fpr ',' FT=fpr -010011011110 "alnv.ps" FD=fpr ',' FS=fpr ',' FT=fpr ',' RS=gpr -0100010011 "c." CO=FCOND '.' F=FMT FS=fpr ',' FT=fpr -01000100000001010 "ceil.l." F=FMT FD=fpr ',' FS=fpr -01000100000001110 "ceil.w." F=FMT FD=fpr ',' FS=fpr +01000100000000101 "abs" F=fmt FD=fpr ',' FS=fpr +010001000000 "add" F=fmt FD=fpr ',' FS=fpr ',' FT=fpr +010011011110 "alnv" ".ps" FD=fpr ',' FS=fpr ',' FT=fpr ',' RS=gpr +01000100000001010 "ceil" ".l" F=fmt FD=fpr ',' FS=fpr +01000100000001110 "ceil" ".w" F=fmt FD=fpr ',' FS=fpr 0100010001000000000000 "cfc1" RT=gpr ',' FS=fpr 0100010011000000000000 "ctc1" RT=gpr ',' FS=fpr -01000100000100001 "cvt.d." F=FMT FD=fpr ',' FS=fpr -01000100000100101 "cvt.l." F=FMT FD=fpr ',' FS=fpr -01000110000100110 "cvt.ps.s" FD=fpr ',' FS=fpr ',' FT=fpr -01000100000100000 "cvt.s." F=FMT FD=fpr ',' FS=fpr -0100011011000000101000 "cvt.s.pl" FS=fpr ',' FD=fpr -0100011011000000100000 "cvt.s.pu" FS=fpr ',' FD=fpr -01000100000100100 "cvt.w." F=FMT FD=fpr ',' FS=fpr -010001000011 "div." F=FMT FD=fpr ',' FS=fpr ',' FT=fpr -01000100000001011 "floor.l." F=FMT FD=fpr ',' FS=fpr -01000100000001111 "floor.w." F=FMT FD=fpr ',' FS=fpr +01000100000100001 "cvt" ".d" F=fmt FD=fpr ',' FS=fpr +01000100000100101 "cvt" ".l" F=fmt FD=fpr ',' FS=fpr +01000110000100110 "cvt" ".ps" ".s" FD=fpr ',' FS=fpr ',' FT=fpr +01000100000100000 "cvt" ".s" F=fmt FD=fpr ',' FS=fpr +0100011011000000101000 "cvt" ".s" ".pl" FS=fpr ',' FD=fpr +0100011011000000100000 "cvt" ".s" ".pu" FS=fpr ',' FD=fpr +01000100000100100 "cvt" ".w" F=fmt FD=fpr ',' FS=fpr +010001000011 "div" F=fmt FD=fpr ',' FS=fpr ',' FT=fpr +01000100000001011 "floor" ".l" F=fmt FD=fpr ',' FS=fpr +01000100000001111 "floor" ".w" F=fmt FD=fpr ',' FS=fpr 110101 "ldc1" FT=fpr ',' IMM=e16 '(' RS=gpr ')' 01001100000000001 "ldxc1" FD=fpr ',' RT=gpr '(' RS=gpr ')' 01001100000000101 "luxc1" FD=fpr ',' RT=gpr '(' RS=gpr ')' 110001 "lwc1" FT=fpr ',' IMM=e16 '(' RS=gpr ')' 01001100000000000 "lwxc1" FD=fpr ',' RT=gpr '(' RS=gpr ')' -010011100 "madd." F=FMT3 FD=fpr ',' FR=fpr ',' FS=fpr ',' FT=fpr +010011100 "madd" F=fmt3 FD=fpr ',' FR=fpr ',' FS=fpr ',' FT=fpr 0100010000000000000000 "mfc1" RT=gpr ',' FS=fpr 0100010001100000000000 "mfhc1" RT=gpr ',' FS=fpr -01000100000000110 "mov." F=FMT FD=fpr ',' FS=fpr -0000000000000000001 "movf" RD=gpr ',' RS=gpr ',' C=FCOND -01000100010001 "movf." F=FMT FD=fpr ',' FS=fpr ',' C=FCOND -010001010011 "movn." F=FMT FD=fpr ',' FS=fpr ',' RT=gpr -0000000100000000001 "movt" RD=gpr ',' RS=gpr ',' C=FCOND -01000101010001 "movt." F=FMT FD=fpr ',' FS=fpr ',' C=FCOND -010001010010 "movz." F=FMT FD=fpr ',' FS=fpr ',' RT=gpr -010011101 "msub." F=FMT3 FD=fpr ',' FR=fpr ',' FS=fpr ',' FT=fpr +01000100000000110 "mov" F=fmt FD=fpr ',' FS=fpr +0000000000000000001 "movf" RD=gpr ',' RS=gpr ',' C=u3 +01000100010001 "movf" F=fmt FD=fpr ',' FS=fpr ',' C=u3 +010001010011 "movn" F=fmt FD=fpr ',' FS=fpr ',' RT=gpr +0000000100000000001 "movt" RD=gpr ',' RS=gpr ',' C=u3 +01000101010001 "movt" F=fmt FD=fpr ',' FS=fpr ',' C=u3 +010001010010 "movz" F=fmt FD=fpr ',' FS=fpr ',' RT=gpr +010011101 "msub" F=fmt3 FD=fpr ',' FR=fpr ',' FS=fpr ',' FT=fpr 0100010010000000000000 "mtc1" RT=gpr ',' FS=fpr 0100010011100000000000 "mthc1" RT=gpr ',' FS=fpr -010001000010 "mul." F=FMT FD=fpr ',' FS=fpr ',' FT=fpr -01000100000000111 "neg." F=FMT FD=fpr ',' FS=fpr -010011110 "nmadd." F=FMT3 FD=fpr ',' FR=fpr ',' FS=fpr ',' FT=fpr -010011111 "nmsub." F=FMT3 FD=fpr ',' FR=fpr ',' FS=fpr ',' FT=fpr -01000110110101100 "pll.ps" FD=fpr ',' FS=fpr ',' FT=fpr -01000110110101101 "plu.ps" FD=fpr ',' FS=fpr ',' FT=fpr -01000110110101110 "pul.ps" FD=fpr ',' FS=fpr ',' FT=fpr -01000110110101111 "puu.ps" FD=fpr ',' FS=fpr ',' FT=fpr -01000100000010101 "recip." F=FMT FD=fpr ',' FS=fpr -01000100000001000 "round.l." F=FMT FD=fpr ',' FS=fpr -01000100000001100 "round.w." F=FMT FD=fpr ',' FS=fpr -01000100000010110 "rsqrt." F=FMT FD=fpr ',' FS=fpr +010001000010 "mul" F=fmt FD=fpr ',' FS=fpr ',' FT=fpr +01000100000000111 "neg" F=fmt FD=fpr ',' FS=fpr +010011110 "nmadd" F=fmt3 FD=fpr ',' FR=fpr ',' FS=fpr ',' FT=fpr +010011111 "nmsub" F=fmt3 FD=fpr ',' FR=fpr ',' FS=fpr ',' FT=fpr +01000110110101100 "pll" ".ps" FD=fpr ',' FS=fpr ',' FT=fpr +01000110110101101 "plu" ".ps" FD=fpr ',' FS=fpr ',' FT=fpr +01000110110101110 "pul" ".ps" FD=fpr ',' FS=fpr ',' FT=fpr +01000110110101111 "puu" ".ps" FD=fpr ',' FS=fpr ',' FT=fpr +01000100000010101 "recip." F=fmt FD=fpr ',' FS=fpr +01000100000001000 "round" ".l" F=fmt FD=fpr ',' FS=fpr +01000100000001100 "round" ".w" F=fmt FD=fpr ',' FS=fpr +01000100000010110 "rsqrt" F=fmt FD=fpr ',' FS=fpr 111101 "sdc1" FT=fpr ',' IMM=e16 '(' RS=gpr ')' 01001100000001001 "sdxc1" FD=fpr ',' RT=gpr '(' RS=gpr ')' -01000100000000100 "sqrt." F=FMT FD=fpr ',' FS=fpr -010001000001 "sub." F=FMT FD=fpr ',' FS=fpr ',' FT=fpr +01000100000000100 "sqrt" F=fmt FD=fpr ',' FS=fpr +010001000001 "sub" F=fmt FD=fpr ',' FS=fpr ',' FT=fpr 01001100000001101 "suxc1" FD=fpr ',' RT=gpr '(' RS=gpr ')' 111001 "swc1" FT=fpr ',' IMM=e16 '(' RS=gpr ')' 01001100000001000 "swxc1" FD=fpr ',' RT=gpr '(' RS=gpr ')' # Generic coprocessor instructions. +0100010011 "c" CO=fcond F=fmt C=u3 ',' FS=fpr ',' FT=fpr 0100010100000 "bc1f" C=u3 ',' OFF=offset16 0100010100000000 "bc1f" OFF=offset16 0100010100010 "bc1fl" C=u3 ',' OFF=offset16 diff --git a/mach/mips/as/mach2.c b/mach/mips/as/mach2.c index db6a311f8..9c81ed9a8 100644 --- a/mach/mips/as/mach2.c +++ b/mach/mips/as/mach2.c @@ -1,7 +1,5 @@ %token GPR %token FPR -%token FMT -%token FMT3 %token FCOND %token OP_LI @@ -12,6 +10,9 @@ %type u25 u20 u16 u5 u3 %type abs26 offset16 +%type fmt fmt3 +%type fcond + %type extmsblsb insmsblsb #include "definitions.y" diff --git a/mach/mips/as/mach3.c b/mach/mips/as/mach3.c index 4e346d742..d75845e7b 100644 --- a/mach/mips/as/mach3.c +++ b/mach/mips/as/mach3.c @@ -74,37 +74,6 @@ 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", diff --git a/mach/mips/as/mach4.c b/mach/mips/as/mach4.c index 3cce17e66..fddeb25c7 100644 --- a/mach/mips/as/mach4.c +++ b/mach/mips/as/mach4.c @@ -34,6 +34,32 @@ 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 { diff --git a/mach/mips/as/mktables.lua b/mach/mips/as/mktables.lua index cb8565fc4..f1214e248 100755 --- a/mach/mips/as/mktables.lua +++ b/mach/mips/as/mktables.lua @@ -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) diff --git a/mach/mips/mcg/table b/mach/mips/mcg/table index fc69ba7de..054a39bdd 100644 --- a/mach/mips/mcg/table +++ b/mach/mips/mcg/table @@ -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 : */