From fe5ca5a85f01b494d55d2373d42e06f0e2d75c7c Mon Sep 17 00:00:00 2001 From: David Given Date: Mon, 3 Sep 2018 22:47:41 +0200 Subject: [PATCH] Added li and la instructions. --- h/out.h | 3 ++- mach/mips/as/instructions.dat | 7 ++++--- mach/mips/as/mach1.c | 9 --------- mach/mips/as/mach2.c | 3 +++ mach/mips/as/mach3.c | 3 +++ mach/mips/as/mach4.c | 31 +++++++++++++++++++++++++++++++ mach/mips/mcg/table | 20 ++++++++++---------- 7 files changed, 53 insertions(+), 23 deletions(-) diff --git a/h/out.h b/h/out.h index 17a4c908c..4176fd341 100644 --- a/h/out.h +++ b/h/out.h @@ -68,7 +68,8 @@ struct outname { #define RELOPPC 4 /* PowerPC 26-bit address */ #define RELOPPC_LIS 5 /* PowerPC lis */ #define RELOVC4 6 /* VideoCore IV address in 32-bit instruction */ -#define RELOMIPS 7 /* MIPS */ +#define RELOMIPS 7 /* MIPS, low half of word or other*/ +#define RELOMIPSHI 8 /* MIPS, high half of word */ #define RELPC 0x2000 /* pc relative */ #define RELBR 0x4000 /* High order byte lowest address. */ diff --git a/mach/mips/as/instructions.dat b/mach/mips/as/instructions.dat index bb46958ba..80af89fdc 100644 --- a/mach/mips/as/instructions.dat +++ b/mach/mips/as/instructions.dat @@ -9,13 +9,14 @@ # Useful pseudoops. -0000000000000000100000 "mov" RD=gpr ',' RS=gpr +# or RD, RS, zero +0000000000000000100101 "mov" RD=gpr ',' RS=gpr # Core ALU instructions. 00000000000100000 "add" RD=gpr ',' RS=gpr ',' RT=gpr -001000 "addi" RT=gpr ',' RT=gpr ',' IMM=e16 -001001 "addiu" RT=gpr ',' RT=gpr ',' IMM=e16 +001000 "addi" RT=gpr ',' RS=gpr ',' IMM=e16 +001001 "addiu" RT=gpr ',' RS=gpr ',' IMM=e16 00000000000100001 "addu" RD=gpr ',' RS=gpr ',' RT=gpr 00000000000100100 "and" RD=gpr ',' RS=gpr ',' RT=gpr 001100 "andi" RT=gpr ',' RS=gpr ',' IMM=e16 diff --git a/mach/mips/as/mach1.c b/mach/mips/as/mach1.c index 50f799684..55c6b5507 100644 --- a/mach/mips/as/mach1.c +++ b/mach/mips/as/mach1.c @@ -1,12 +1,3 @@ -/* - * $Source$ - * $State$ - */ - /* * Do not #include anything here. Do it in mach/proto/as/comm0.h */ - -void no_hl(void); -word_t eval_hl(struct expr_t* expr, int token); -void emit_hl(word_t in); diff --git a/mach/mips/as/mach2.c b/mach/mips/as/mach2.c index 11886d052..db6a311f8 100644 --- a/mach/mips/as/mach2.c +++ b/mach/mips/as/mach2.c @@ -4,6 +4,9 @@ %token FMT3 %token FCOND +%token OP_LI +%token OP_LA + %type gpr fpr %type e16 e9 %type u25 u20 u16 u5 u3 diff --git a/mach/mips/as/mach3.c b/mach/mips/as/mach3.c index 45af1c4fd..4e346d742 100644 --- a/mach/mips/as/mach3.c +++ b/mach/mips/as/mach3.c @@ -105,5 +105,8 @@ 0, FMT3, 5, "l", 0, FMT3, 6, "ps", +0, OP_LI, 0, "li", +0, OP_LA, 0, "la", + #include "tokens.y" diff --git a/mach/mips/as/mach4.c b/mach/mips/as/mach4.c index f4d4c5e8d..3cce17e66 100644 --- a/mach/mips/as/mach4.c +++ b/mach/mips/as/mach4.c @@ -1,4 +1,35 @@ #include "rules.y" + | OP_LI GPR ',' expr + { + word_t reg = $2; + word_t type = $4.typ & S_TYP; + word_t val = $4.val; + if (type != S_ABS) + serror("li cannot be used with values that need a fixup"); + + if (val == 0) + emit4(0x00000025 | (reg<<11)); /* or reg, zero, zero */ + else if ((val < -0x8000) || (val > 0xffff)) + emit4(0x24000000 | (reg<<16) | (val & 0xffff)); /* addiu reg, zero, value */ + else + { + emit4(0x3c000000 | (reg<<16) | (val>>16)); /* lui reg, value */ + emit4(0x34000000 | (reg<<16) | (reg<<21) | (val & 0xffff)); /* ori reg, reg, value */ + } + } + | OP_LA GPR ',' expr + { + word_t reg = $2; + word_t type = $4.typ & S_TYP; + word_t val = $4.val; + + if (type != S_ABS) + newrelo($4.typ, RELOMIPSHI | FIXUPFLAGS); + emit4(0x3c000000 | (reg<<16) | (val>>16)); /* lui reg, value */ + if (type != S_ABS) + newrelo($4.typ, RELOMIPS | FIXUPFLAGS); + emit4(0x34000000 | (reg<<16) | (reg<<21) | (val & 0xffff)); /* ori reg, reg, value */ + } gpr: GPR fpr: FPR diff --git a/mach/mips/mcg/table b/mach/mips/mcg/table index 53b73fa53..fc69ba7de 100644 --- a/mach/mips/mcg/table +++ b/mach/mips/mcg/table @@ -635,15 +635,15 @@ PATTERNS ALUR(DIV.I, "divw") ALUR(DIVU.I, "divwu") - ALUR(ASL.I, "sll") - ALUC(ASL.I, "sllv") - ALUR(ASR.I, "sra") - ALUC(ASR.I, "srav") + ALUR(ASL.I, "sllv") + ALUC(ASL.I, "sll") + ALUR(ASR.I, "srav") + ALUC(ASR.I, "sra") - ALUR(LSL.I, "sll") - ALUC(LSL.I, "sllv") - ALUR(LSR.I, "srl") - ALUC(LSR.I, "srlv") + ALUR(LSL.I, "sllv") + ALUC(LSL.I, "sll") + ALUR(LSR.I, "srlv") + ALUC(LSR.I, "srl") out:(int)reg = NEG.I(left:(int)reg) emit "neg %out, %left" @@ -663,11 +663,11 @@ PATTERNS ALUCC(EOR.I, "xori") out:(int)reg = value:LABEL.I - emit "li32 %out, $value" + emit "la %out, $value" cost 4; out:(int)reg = value:BLOCK.I - emit "li32 %out, $value" + emit "la %out, $value" cost 4; out:(int)reg = value:CONST.I