Massive change to how IR types are handled; we use the type code for matching

rather than the size. Much cleaner and simpler.
This commit is contained in:
David Given 2016-10-23 21:54:14 +02:00
parent b1a3d76d6f
commit abd0cedd61
11 changed files with 419 additions and 311 deletions

View file

@ -99,7 +99,7 @@ struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg*
{ {
struct hop* hop = new_hop(bb, NULL); struct hop* hop = new_hop(bb, NULL);
const uint32_t type_attrs = const uint32_t type_attrs =
burm_int_ATTR | burm_pair_ATTR | burm_float_ATTR | burm_double_ATTR; burm_int_ATTR | burm_long_ATTR | burm_float_ATTR | burm_double_ATTR;
if ((src->type & type_attrs) != (dest->type & type_attrs)) if ((src->type & type_attrs) != (dest->type & type_attrs))
{ {
@ -112,7 +112,7 @@ struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg*
hop_add_insel(hop, "stwu %H, -4(sp)", src); hop_add_insel(hop, "stwu %H, -4(sp)", src);
break; break;
case burm_pair_ATTR: case burm_long_ATTR:
hop_add_insel(hop, "stwu %0H, -4(sp)", src); hop_add_insel(hop, "stwu %0H, -4(sp)", src);
hop_add_insel(hop, "stwu %1H, -4(sp)", src); hop_add_insel(hop, "stwu %1H, -4(sp)", src);
break; break;
@ -135,7 +135,7 @@ struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg*
hop_add_insel(hop, "lwz %H, 0(sp)", dest); hop_add_insel(hop, "lwz %H, 0(sp)", dest);
break; break;
case burm_pair_ATTR: case burm_long_ATTR:
hop_add_insel(hop, "lwz %0H, 4(sp)", dest); hop_add_insel(hop, "lwz %0H, 4(sp)", dest);
hop_add_insel(hop, "lwz %1H, 0(sp)", dest); hop_add_insel(hop, "lwz %1H, 0(sp)", dest);
break; break;
@ -160,7 +160,7 @@ struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg*
break; break;
case burm_double_ATTR: case burm_double_ATTR:
case burm_pair_ATTR: case burm_long_ATTR:
hop_add_insel(hop, "addi sp, sp, 8"); hop_add_insel(hop, "addi sp, sp, 8");
break; break;
@ -220,7 +220,7 @@ struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg*
hop_add_insel(hop, "mr %H, %H", dest, src); hop_add_insel(hop, "mr %H, %H", dest, src);
break; break;
case burm_pair_ATTR: case burm_long_ATTR:
hop_add_insel(hop, "mr %0H, %0H", dest, src); hop_add_insel(hop, "mr %0H, %0H", dest, src);
hop_add_insel(hop, "mr %1H, %1H", dest, src); hop_add_insel(hop, "mr %1H, %1H", dest, src);
break; break;

View file

@ -38,21 +38,21 @@ REGISTERS
r14 bytes4! int!; r14 bytes4! int!;
r13 bytes4! int!; r13 bytes4! int!;
r11r12 named("r11", "r12") aliases(r11, r12) bytes8! pair! volatile; r11r12 named("r11", "r12") aliases(r11, r12) bytes8! long! volatile;
r9r10 named("r9", "r10") aliases(r9, r10) bytes8! pair! volatile; r9r10 named("r9", "r10") aliases(r9, r10) bytes8! long! volatile;
r7r8 named("r7", "r8") aliases(r7, r8) bytes8! pair! volatile; r7r8 named("r7", "r8") aliases(r7, r8) bytes8! long! volatile;
r5r6 named("r5", "r6") aliases(r6, r6) bytes8! pair! volatile; r5r6 named("r5", "r6") aliases(r6, r6) bytes8! long! volatile;
r3r4 named("r3", "r4") aliases(r3, r4) bytes8! pair! volatile pret; r3r4 named("r3", "r4") aliases(r3, r4) bytes8! long! volatile pret;
r29r30 named("r29", "r30") aliases(r29, r30) bytes8! pair!; r29r30 named("r29", "r30") aliases(r29, r30) bytes8! long!;
r27r28 named("r27", "r28") aliases(r27, r28) bytes8! pair!; r27r28 named("r27", "r28") aliases(r27, r28) bytes8! long!;
r25r26 named("r25", "r26") aliases(r25, r26) bytes8! pair!; r25r26 named("r25", "r26") aliases(r25, r26) bytes8! long!;
r23r24 named("r23", "r24") aliases(r23, r24) bytes8! pair!; r23r24 named("r23", "r24") aliases(r23, r24) bytes8! long!;
r21r22 named("r21", "r22") aliases(r21, r22) bytes8! pair!; r21r22 named("r21", "r22") aliases(r21, r22) bytes8! long!;
r19r20 named("r19", "r20") aliases(r19, r20) bytes8! pair!; r19r20 named("r19", "r20") aliases(r19, r20) bytes8! long!;
r17r18 named("r17", "r18") aliases(r17, r18) bytes8! pair!; r17r18 named("r17", "r18") aliases(r17, r18) bytes8! long!;
r15r16 named("r15", "r16") aliases(r15, r16) bytes8! pair!; r15r16 named("r15", "r16") aliases(r15, r16) bytes8! long!;
r13r14 named("r13", "r14") aliases(r13, r14) bytes8! pair!; r13r14 named("r13", "r14") aliases(r13, r14) bytes8! long!;
f14 bytes4! float! volatile; f14 bytes4! float! volatile;
f13 bytes4! float! volatile; f13 bytes4! float! volatile;
@ -142,73 +142,90 @@ PATTERNS
/* Special */ /* Special */
PAIR(BLOCK4, BLOCK4); PAIR(BLOCK.I, BLOCK.I);
/* Miscellaneous special things */ /* Miscellaneous special things */
PUSH4(in:(int)reg) PUSH.I(in:(int)reg)
emit "stwu %in, -4(sp)" emit "stwu %in, -4(sp)"
cost 4; cost 4;
PUSH8(in:(pair)reg) PUSH.L(in:(long)reg)
emit "stwu %in.0, -4(sp)" emit "stwu %in.0, -4(sp)"
emit "stwu %in.1, -4(sp)" emit "stwu %in.1, -4(sp)"
cost 8; cost 8;
out:(int)reg = POP4 PUSH.D(in:(double)reg)
emit "stfdu %in, -8(sp)"
cost 4;
out:(int)reg = POP.I
emit "lwz %out, 0(sp)" emit "lwz %out, 0(sp)"
emit "addi sp, sp, 4" emit "addi sp, sp, 4"
cost 8; cost 8;
out:(pair)reg = POP8 out:(long)reg = POP.L
emit "lwz %out.0, 4(sp)" emit "lwz %out.0, 4(sp)"
emit "lwz %out.1, 0(sp)" emit "lwz %out.1, 0(sp)"
emit "addi sp, sp, 8" emit "addi sp, sp, 8"
cost 12; cost 12;
out:(float)reg = POPF4 out:(float)reg = POP.F
emit "lfs %out, 0(sp)" emit "lfs %out, 0(sp)"
emit "addi sp, sp, 4" emit "addi sp, sp, 4"
cost 8; cost 8;
SETRET4(in:(ret)reg) SETRET.I(in:(ret)reg)
emit "! setret4" emit "! setret4"
cost 1; cost 1;
SETRET8(in:(pret)reg) SETRET.L(in:(pret)reg)
emit "! setret8" emit "! setret8"
cost 1; cost 1;
STACKADJUST4(delta:CONST4) STACKADJUST.I(delta:CONST.I)
when signed_constant(%delta, 16) when signed_constant(%delta, 16)
emit "addi sp, sp, $delta" emit "addi sp, sp, $delta"
cost 4; cost 4;
STACKADJUST4(in:(int)reg) STACKADJUST.I(in:(int)reg)
emit "add sp, sp, %in" emit "add sp, sp, %in"
cost 4; cost 4;
out:(int)reg = GETFP4 out:(int)reg = GETFP.I
emit "mr %out, fp" emit "mr %out, fp"
cost 4; cost 4;
out:(int)reg = FPTOARGS4(GETFP4) out:(int)reg = FPTOARGS.I(GETFP.I)
emit "addi %out, fp, 8" emit "addi %out, fp, 8"
cost 4; cost 4;
out:(int)reg = FPTOARGS4(in:(int)reg) out:(int)reg = FPTOARGS.I(in:(int)reg)
emit "addi %out, %in, 8" emit "addi %out, %in, 8"
cost 4; cost 4;
out:(int)reg = GETSP4 out:(int)reg = GETSP.I
emit "mr %out, sp" emit "mr %out, sp"
cost 4; cost 4;
SETSP4(in:(int)reg) SETSP.I(in:(int)reg)
emit "mr sp, %in" emit "mr sp, %in"
cost 4; cost 4;
out:(int)reg = COPYF.I(in:(float)reg)
emit "stfsu %in, -4(sp)"
emit "lwz %out, 0(sp)"
emit "addi sp, sp, 4"
cost 12;
out:(double)reg = COPYL.D(in:(long)reg)
emit "stwu %in.0, -4(sp)"
emit "stwu %in.1, -4(sp)"
emit "lfd %out, 0(sp)"
emit "addi sp, sp, 8"
cost 16;
@ -216,47 +233,55 @@ PATTERNS
/* Stores */ /* Stores */
STORE8(addr:address, value:(pair)reg) STORE.L(addr:address, value:(long)reg)
emit "stw %value.0, 4+%addr" emit "stw %value.0, 4+%addr"
emit "stw %value.1, 0+%addr" emit "stw %value.1, 0+%addr"
cost 4; cost 4;
STORE4(addr:address, value:(int)reg) STORE.I(addr:address, value:(int)reg)
emit "stw %value, %addr" emit "stw %value, %addr"
cost 4; cost 4;
STORE2(addr:address, value:(int)ushortX) STOREH.I(addr:address, value:(int)ushortX)
emit "sth %value, %addr" emit "sth %value, %addr"
cost 4; cost 4;
STORE2(ADD4(left:(int)reg, right:(int)reg), value:(int)ushortX) STOREH.I(ADD.I(left:(int)reg, right:(int)reg), value:(int)ushortX)
emit "sthx %value, %left, %right" emit "sthx %value, %left, %right"
cost 4; cost 4;
STORE1(addr:address, value:(int)ubyteX) STOREB.I(addr:address, value:(int)ushortX)
emit "sth %value, %addr"
cost 4;
STOREB.I(addr:address, value:(int)ubyteX)
emit "stb %value, %addr" emit "stb %value, %addr"
cost 4; cost 4;
STORE1(ADD4(left:(int)reg, right:(int)reg), value:(int)ubyteX) STOREB.I(ADD.I(left:(int)reg, right:(int)reg), value:(int)ubyteX)
emit "stbx %value, %left, %right" emit "stbx %value, %left, %right"
cost 4; cost 4;
/* Loads */ /* Loads */
out:(int)reg = LOAD4(addr:address) out:(int)reg = LOAD.I(addr:address)
emit "lwz %out, %addr" emit "lwz %out, %addr"
cost 4; cost 4;
out:(pair)reg = LOAD8(addr:address) out:(long)reg = LOAD.L(addr:address)
emit "lwz %out.0, 4+%addr" emit "lwz %out.0, 4+%addr"
emit "lwz %out.1, 0+%addr" emit "lwz %out.1, 0+%addr"
cost 8; cost 8;
out:(int)ushort0 = LOAD2(addr:address) out:(double)reg = LOAD.D(addr:address)
emit "lfsd %out, %addr"
cost 4;
out:(int)ushort0 = LOADH.I(addr:address)
emit "lhz %out, %addr" emit "lhz %out, %addr"
cost 4; cost 4;
out:(int)ubyte0 = LOAD1(addr:address) out:(int)ubyte0 = LOADB.I(addr:address)
emit "lbz %out, %addr" emit "lbz %out, %addr"
cost 4; cost 4;
@ -302,6 +327,38 @@ PATTERNS
emit "! reg -> ushortX" emit "! reg -> ushortX"
cost 1; cost 1;
/* Extensions and conversions */
out:(int)reg = EXTENDB.I(in:(int)reg)
emit "extsb %out, %in"
cost 4;
out:(int)reg = EXTENDH.I(in:(int)reg)
emit "extsh %out, %in"
cost 4;
out:(int)reg = FROMSI.I(in:(int)reg)
with %out == %in
emit "! FROMSI.I(int) -> int"
cost 1;
out:(int)reg = FROMUI.I(in:(int)reg)
with %out == %in
emit "! FROMUI.I(int) -> int"
cost 1;
out:(long)reg = FROMSI.L(in:(int)reg)
emit "mr %out.0, %in"
emit "srawi %out.1, %out.0, 31"
cost 8;
out:(int)reg = FROMD.I(in:(double)reg)
with corrupted(volatile)
emit "bl .fromd2i"
cost 4;
#if 0
/* byte conversions */ /* byte conversions */
out:(int)ubyte0 = CIU14(in:(int)ubyte0) out:(int)ubyte0 = CIU14(in:(int)ubyte0)
@ -348,22 +405,23 @@ PATTERNS
out:(int)reg = CII24(in:(int)ushortX) out:(int)reg = CII24(in:(int)ushortX)
emit "extsh %out, %in" emit "extsh %out, %in"
cost 4; cost 4;
#endif
/* Locals */ /* Locals */
out:(int)reg = in:LOCAL4 out:(int)reg = in:LOCAL.I
emit "addi %out, fp, $in" emit "addi %out, fp, $in"
cost 4; cost 4;
address = in:LOCAL4 address = in:LOCAL.I
emit "$in(fp)"; emit "$in(fp)";
/* Memory addressing modes */ /* Memory addressing modes */
address = ADD4(addr:(int)reg, offset:CONST4) address = ADD.I(addr:(int)reg, offset:CONST.I)
when signed_constant(%offset, 16) when signed_constant(%offset, 16)
emit "$offset(%addr)"; emit "$offset(%addr)";
@ -374,59 +432,59 @@ PATTERNS
/* Branches */ /* Branches */
JUMP(addr:BLOCK4) JUMP(addr:BLOCK.I)
emit "b $addr" emit "b $addr"
cost 4; cost 4;
CJUMPEQ(value:(cr)cr, PAIR(true:BLOCK4, false:BLOCK4)) CJUMPEQ(value:(cr)cr, PAIR(true:BLOCK.I, false:BLOCK.I))
emit "bc 12, 2, $true" /* IFTRUE EQ */ emit "bc 12, 2, $true" /* IFTRUE EQ */
emit "b $false" emit "b $false"
cost 8; cost 8;
CJUMPLE(value:(cr)cr, PAIR(true:BLOCK4, false:BLOCK4)) CJUMPLE(value:(cr)cr, PAIR(true:BLOCK.I, false:BLOCK.I))
emit "bc 4, 1, $true" /* IFFALSE GT */ emit "bc 4, 1, $true" /* IFFALSE GT */
emit "b $false" emit "b $false"
cost 8; cost 8;
CJUMPLT(value:(cr)cr, PAIR(true:BLOCK4, false:BLOCK4)) CJUMPLT(value:(cr)cr, PAIR(true:BLOCK.I, false:BLOCK.I))
emit "bc 12, 0, $true" /* IFTRUE LT */ emit "bc 12, 0, $true" /* IFTRUE LT */
emit "b $false" emit "b $false"
cost 8; cost 8;
CALL1(dest:LABEL4) CALL(dest:LABEL.I)
with corrupted(volatile) with corrupted(volatile)
emit "bl $dest" emit "bl $dest"
cost 4; cost 4;
out:(ret)reg = CALL4(dest:LABEL4) out:(ret)reg = CALL.I(dest:LABEL.I)
with corrupted(volatile) with corrupted(volatile)
emit "bl $dest" emit "bl $dest"
cost 4; cost 4;
out:(pret)reg = CALL8(dest:LABEL4) out:(pret)reg = CALL.L(dest:LABEL.I)
with corrupted(volatile) with corrupted(volatile)
emit "bl $dest" emit "bl $dest"
cost 4; cost 4;
CALL1(dest:(int)reg) CALL(dest:(int)reg)
with corrupted(volatile) with corrupted(volatile)
emit "mtspr ctr, %dest" emit "mtspr ctr, %dest"
emit "bcctrl 20, 0, 0" emit "bcctrl 20, 0, 0"
cost 8; cost 8;
out:(ret)reg = CALL4(dest:(int)reg) out:(ret)reg = CALL.I(dest:(int)reg)
with corrupted(volatile) with corrupted(volatile)
emit "mtspr ctr, %dest" emit "mtspr ctr, %dest"
emit "bcctrl 20, 0, 0" emit "bcctrl 20, 0, 0"
cost 8; cost 8;
out:(pret)reg = CALL8(dest:(int)reg) out:(pret)reg = CALL.L(dest:(int)reg)
with corrupted(volatile) with corrupted(volatile)
emit "mtspr ctr, %dest" emit "mtspr ctr, %dest"
emit "bcctrl 20, 0, 0" emit "bcctrl 20, 0, 0"
cost 8; cost 8;
JUMP(dest:LABEL4) JUMP(dest:LABEL.I)
emit "b $dest" emit "b $dest"
cost 4; cost 4;
@ -434,40 +492,40 @@ PATTERNS
/* Comparisons */ /* Comparisons */
cr:(cr)cr = COMPARES44(left:(int)reg, right:(int)reg) cr:(cr)cr = COMPARESI.I(left:(int)reg, right:(int)reg)
emit "cmp %cr, 0, %left, %right" emit "cmp %cr, 0, %left, %right"
cost 4; cost 4;
cr:(cr)cr = COMPARES44(left:(int)reg, right:CONST4) cr:(cr)cr = COMPARESI.I(left:(int)reg, right:CONST.I)
when signed_constant(%right, 16) when signed_constant(%right, 16)
emit "cmpi %cr, 0, %left, $right" emit "cmpi %cr, 0, %left, $right"
cost 4; cost 4;
cr:(cr)cr = COMPAREU44(left:(int)reg, right:(int)reg) cr:(cr)cr = COMPAREUI.I(left:(int)reg, right:(int)reg)
emit "cmpl %cr, 0, %left, %right" emit "cmpl %cr, 0, %left, %right"
cost 4; cost 4;
cr:(cr)cr = COMPAREU44(left:(int)reg, right:CONST4) cr:(cr)cr = COMPAREUI.I(left:(int)reg, right:CONST.I)
when signed_constant(%right, 16) when signed_constant(%right, 16)
emit "cmpli %cr, 0, %left, $right" emit "cmpli %cr, 0, %left, $right"
cost 4; cost 4;
out:(cr)cr = COMPARES44(in:(cr)cr, result:CONST4) out:(cr)cr = COMPARESI.I(in:(cr)cr, result:CONST.I)
when specific_constant(%result, 0) when specific_constant(%result, 0)
with %out == %in with %out == %in
emit "! COMPARES(cr, 0)" emit "! COMPARESI.I(cr, 0)"
cost 4; cost 4;
/* Booleans */ /* Booleans */
out:(int)reg = IFEQ4(in:(cr)cr) out:(int)reg = IFEQ.I(in:(cr)cr)
emit "mfcr %out" /* get cr0 */ emit "mfcr %out" /* get cr0 */
emit "rlwinm %out, %out, [32-2], 2, 31" /* extract just EQ */ emit "rlwinm %out, %out, [32-2], 2, 31" /* extract just EQ */
cost 8; cost 8;
out:(int)reg = IFEQ4(in:(int)reg) out:(int)reg = IFEQ.I(in:(int)reg)
emit "cntlzw %out, %in" /* returns 0..32 */ emit "cntlzw %out, %in" /* returns 0..32 */
emit "rlwinm %out, %out, [32-5], 5, 31" /* if 32, return 1, otherwise 0 */ emit "rlwinm %out, %out, [32-5], 5, 31" /* if 32, return 1, otherwise 0 */
cost 8; cost 8;
@ -476,6 +534,7 @@ PATTERNS
/* Conversions */ /* Conversions */
#if 0
out:(int)reg = CIU44(in:(int)reg) out:(int)reg = CIU44(in:(int)reg)
with %out == %in with %out == %in
emit "! ciu44" emit "! ciu44"
@ -485,7 +544,7 @@ PATTERNS
with %out == %in with %out == %in
emit "! cui44" emit "! cui44"
cost 4; cost 4;
#endif
/* ALU operations */ /* ALU operations */
@ -495,13 +554,13 @@ PATTERNS
cost 4; \ cost 4; \
#define ALUC(name, instr) \ #define ALUC(name, instr) \
out:(int)reg = name(left:(int)reg, right:CONST4) \ out:(int)reg = name(left:(int)reg, right:CONST.I) \
when signed_constant(%right, 16) \ when signed_constant(%right, 16) \
emit instr " %out, %left, $right" \ emit instr " %out, %left, $right" \
cost 4; \ cost 4; \
#define ALUC_reversed(name, instr) \ #define ALUC_reversed(name, instr) \
out:(int)reg = name(left:CONST4, right:(int)reg) \ out:(int)reg = name(left:CONST.I, right:(int)reg) \
when signed_constant(%left, 16) \ when signed_constant(%left, 16) \
emit instr " %out, %right, $left" \ emit instr " %out, %right, $left" \
cost 4; \ cost 4; \
@ -510,66 +569,66 @@ PATTERNS
ALUC(name, instr) \ ALUC(name, instr) \
ALUC_reversed(name, instr) ALUC_reversed(name, instr)
ALUR(ADD4, "add") ALUR(ADD.I, "add")
ALUCC(ADD4, "addi") ALUCC(ADD.I, "addi")
out:(int)reg = SUB4(left:(int)reg, right:(int)reg) out:(int)reg = SUB.I(left:(int)reg, right:(int)reg)
emit "subf %out, %left, %right" emit "subf %out, %left, %right"
cost 4; cost 4;
out:(int)reg = SUB4(left:(int)reg, right:CONST4) out:(int)reg = SUB.I(left:(int)reg, right:CONST.I)
emit "addi %out, %left, -[$right]" emit "addi %out, %left, -[$right]"
cost 4; cost 4;
out:(int)reg = MOD4(left:(int)reg, right:(int)reg) out:(int)reg = MOD.I(left:(int)reg, right:(int)reg)
emit "divw %out, %left, %right" emit "divw %out, %left, %right"
emit "mullw %out, %out, %right" emit "mullw %out, %out, %right"
emit "subf %out, %out, %left" emit "subf %out, %out, %left"
cost 12; cost 12;
out:(int)reg = MODU4(left:(int)reg, right:(int)reg) out:(int)reg = MODU.I(left:(int)reg, right:(int)reg)
emit "divwu %out, %left, %right" emit "divwu %out, %left, %right"
emit "mullw %out, %out, %right" emit "mullw %out, %out, %right"
emit "subf %out, %out, %left" emit "subf %out, %out, %left"
cost 12; cost 12;
ALUR(MUL4, "mullw") ALUR(MUL.I, "mullw")
ALUCC(MUL4, "mulli") ALUCC(MUL.I, "mulli")
ALUR(DIV4, "divw") ALUR(DIV.I, "divw")
ALUR(DIVU4, "divwu") ALUR(DIVU.I, "divwu")
ALUR(ASL4, "slw") ALUR(ASL.I, "slw")
ALUR(LSL4, "slw") ALUR(LSL.I, "slw")
out:(int)reg = NEG4(left:(int)reg) out:(int)reg = NEG.I(left:(int)reg)
emit "neg %out, %left" emit "neg %out, %left"
cost 4; cost 4;
out:(int)reg = NOT4(left:(int)reg) out:(int)reg = NOT.I(left:(int)reg)
emit "cntlzw %out, %left" emit "cntlzw %out, %left"
emit "rlwinm %out, %out, 32-5, 5, 31" emit "rlwinm %out, %out, 32-5, 5, 31"
cost 8; cost 8;
ALUR(AND4, "and") ALUR(AND.I, "and")
ALUCC(AND4, "andi.") ALUCC(AND.I, "andi.")
ALUR(OR4, "or") ALUR(OR.I, "or")
ALUCC(OR4, "ori") ALUCC(OR.I, "ori")
ALUR(EOR4, "xor") ALUR(EOR.I, "xor")
ALUCC(EOR4, "xori") ALUCC(EOR.I, "xori")
out:(int)reg = value:LABEL4 out:(int)reg = value:LABEL.I
emit "la %out, $value" emit "la %out, $value"
cost 4; cost 4;
out:(int)reg = value:BLOCK4 out:(int)reg = value:BLOCK.I
emit "la %out, $value" emit "la %out, $value"
cost 4; cost 4;
out:(int)reg = value:CONST4 out:(int)reg = value:CONST.I
emit "li %out, $value" emit "li %out, $value"
cost 8; cost 8;
@ -586,46 +645,47 @@ PATTERNS
emit instr " %out, %left, %right" \ emit instr " %out, %left, %right" \
cost 4; \ cost 4; \
out:(float)reg = LOADF4(addr:address) out:(float)reg = LOAD.F(addr:address)
emit "lfs %out, %addr" emit "lfs %out, %addr"
cost 4; cost 4;
out:(double)reg = LOADF8(addr:address) out:(double)reg = LOAD.D(addr:address)
emit "lfd %out, %addr" emit "lfd %out, %addr"
cost 4; cost 4;
out:(float)reg = value:CONSTF4 out:(float)reg = value:CONST.F
emit "lfs %out, address-containing-$value" emit "lfs %out, address-containing-$value"
cost 8; cost 8;
FPU4R(ADDF4, "fadds") FPU4R(ADDF.F, "fadds")
FPU8R(ADDF8, "fadd") FPU8R(ADDF.D, "fadd")
FPU4R(SUBF4, "fsubs") FPU4R(SUBF.F, "fsubs")
FPU8R(SUBF8, "fsub") FPU8R(SUBF.D, "fsub")
FPU4R(MULF4, "fmuls") FPU4R(MULF.F, "fmuls")
FPU8R(MULF8, "fmul") FPU8R(MULF.D, "fmul")
FPU4R(DIVF4, "fdivs") FPU4R(DIVF.F, "fdivs")
FPU8R(DIVF8, "fdiv") FPU8R(DIVF.D, "fdiv")
out:(float)reg = NEGF4(left:(float)reg) out:(float)reg = NEGF.F(left:(float)reg)
emit "fneg %out, %left" emit "fneg %out, %left"
cost 4; cost 4;
out:(double)reg = NEGF8(left:(double)reg) out:(double)reg = NEGF.D(left:(double)reg)
emit "fneg %out, %left" emit "fneg %out, %left"
cost 4; cost 4;
cr:(cr)cr = COMPAREF44(left:(float)reg, right:(float)reg) cr:(cr)cr = COMPAREF.I(left:(float)reg, right:(float)reg)
emit "fcmpu %cr, %left, %right" emit "fcmpu %cr, %left, %right"
cost 4; cost 4;
cr:(cr)cr = COMPAREF84(left:(double)reg, right:(double)reg) cr:(cr)cr = COMPARED.I(left:(double)reg, right:(double)reg)
emit "fcmpu %cr, %left, %right" emit "fcmpu %cr, %left, %right"
cost 4; cost 4;
#if 0
out:(ret)reg = CFI44(val:(fret)reg) out:(ret)reg = CFI44(val:(fret)reg)
with corrupted(volatile) with corrupted(volatile)
emit "bl .cfi44" emit "bl .cfi44"
@ -653,6 +713,7 @@ PATTERNS
out:(double)reg = CFF48(val:(float)reg) out:(double)reg = CFF48(val:(float)reg)
emit "fmr %out, %val" emit "fmr %out, %val"
cost 1; cost 1;
#endif
/* vim: set sw=4 ts=4 expandtab : */ /* vim: set sw=4 ts=4 expandtab : */

View file

@ -89,7 +89,6 @@ static void convert_block(struct basicblock* bb)
{ {
struct ir* ir = pushes.item[i].right; struct ir* ir = pushes.item[i].right;
ir->opcode = IR_NOP; ir->opcode = IR_NOP;
ir->size = 0;
} }
for (i=0; i<pops.count; i++) for (i=0; i<pops.count; i++)

View file

@ -210,14 +210,14 @@ static struct insn* walk_instructions(struct burm_node* node, int goal)
{ {
switch (node->label) switch (node->label)
{ {
case ir_to_esn(IR_REG, 1): case ir_to_esn(IR_REG, 0):
case ir_to_esn(IR_REG, 2):
case ir_to_esn(IR_REG, 4):
case ir_to_esn(IR_REG, 8):
current_hop->output = node->ir->result; current_hop->output = node->ir->result;
break; break;
case ir_to_esn(IR_NOP, 0): case ir_to_esn(IR_NOP, 'I'):
case ir_to_esn(IR_NOP, 'F'):
case ir_to_esn(IR_NOP, 'L'):
case ir_to_esn(IR_NOP, 'D'):
current_hop->output = node->left->ir->result; current_hop->output = node->left->ir->result;
break; break;
} }
@ -241,7 +241,7 @@ static struct burm_node* build_shadow_tree(struct ir* root, struct ir* ir)
if (ir->root == root) if (ir->root == root)
{ {
node->label = ir_to_esn(ir->opcode, ir->size); node->label = ir_to_esn(ir->opcode, ir->type);
if (ir->left) if (ir->left)
node->left = build_shadow_tree(root, ir->left); node->left = build_shadow_tree(root, ir->left);

View file

@ -63,11 +63,10 @@ static bool rewrite_loads_cb(struct ir* ir, void* user)
if (ir->right && is_local(ir->right)) if (ir->right && is_local(ir->right))
ir->right = definition; ir->right = definition;
/* Otherwise, go via a IR_REG (which should, with luck, turn into no code). */ /* Otherwise, go via a IR_NOP (which should, with luck, turn into no code). */
if (is_local(ir)) if (is_local(ir))
{ {
ir->opcode = IR_NOP; ir->opcode = IR_NOP;
ir->size = 0;
ir->left = definition; ir->left = definition;
ir->right = NULL; ir->right = NULL;
} }
@ -108,7 +107,6 @@ static void recursively_rewrite_tree(struct basicblock* bb)
if (ir->opcode == IR_STORE) if (ir->opcode == IR_STORE)
{ {
ir->opcode = IR_NOP; ir->opcode = IR_NOP;
ir->size = 0;
ir->left = ir->right; ir->left = ir->right;
ir->right = NULL; ir->right = NULL;
} }

View file

@ -212,11 +212,11 @@ static struct ir* new_copy(char wanted, char real, struct ir* ir)
if ((wanted == 'F') && (real == 'I')) if ((wanted == 'F') && (real == 'I'))
opcode = IR_COPYI; opcode = IR_COPYI;
else if ((wanted == 'D') && (real == 'L')) else if ((wanted == 'D') && (real == 'L'))
opcode = IR_COPYI; opcode = IR_COPYL;
else if ((wanted == 'I') && (real == 'F')) else if ((wanted == 'I') && (real == 'F'))
opcode = IR_COPYF; opcode = IR_COPYF;
else if ((wanted == 'L') && (real == 'D')) else if ((wanted == 'L') && (real == 'D'))
opcode = IR_COPYF; opcode = IR_COPYD;
else else
fatal("type mismatch: parent IR wanted %c, child IR provided %c", fatal("type mismatch: parent IR wanted %c, child IR provided %c",
wanted, real); wanted, real);

View file

@ -6,7 +6,7 @@ static int stackptr;
static struct ir* stack[64]; static struct ir* stack[64];
static struct ir* lastcall; static struct ir* lastcall;
static struct ir* convert(struct ir* src, int destsize, int opcodebase); static struct ir* convert(struct ir* src, int srcsize, int destsize, int opcode);
static struct ir* appendir(struct ir* ir); static struct ir* appendir(struct ir* ir);
static void reset_stack(void) static void reset_stack(void)
@ -19,17 +19,22 @@ static void push(struct ir* ir)
if (stackptr == sizeof(stack)/sizeof(*stack)) if (stackptr == sizeof(stack)/sizeof(*stack))
fatal("stack overflow"); fatal("stack overflow");
#if 0
/* If we try to push something which is too small, convert it to a word /* If we try to push something which is too small, convert it to a word
* first. */ * first. */
if (ir->size < EM_wordsize) if (ir->size < EM_wordsize)
ir = convert(ir, EM_wordsize, IR_CIU1); ir = convertu(ir, EM_wordsize);
#endif
stack[stackptr++] = ir; stack[stackptr++] = ir;
} }
static struct ir* pop(int size) static struct ir* pop(int size)
{ {
if (size < EM_wordsize)
size = EM_wordsize;
if (stackptr == 0) if (stackptr == 0)
{ {
/* Nothing in our fake stack, so we have to read from the real stack. */ /* Nothing in our fake stack, so we have to read from the real stack. */
@ -47,10 +52,12 @@ static struct ir* pop(int size)
{ {
struct ir* ir = stack[--stackptr]; struct ir* ir = stack[--stackptr];
#if 0
/* If we try to pop something which is smaller than a word, convert it first. */ /* If we try to pop something which is smaller than a word, convert it first. */
if (size < EM_wordsize) if (size < EM_wordsize)
ir = convert(ir, size, IR_CIU1); ir = convertu(ir, size);
#endif
if (ir->size != size) if (ir->size != size)
fatal("expected an item on stack of size %d, but got %d\n", size, ir->size); fatal("expected an item on stack of size %d, but got %d\n", size, ir->size);
@ -131,18 +138,39 @@ static struct ir* address_of_external(const char* label, arith offset)
new_labelir(label); new_labelir(label);
} }
static struct ir* convert(struct ir* src, int destsize, int opcode) static struct ir* convert(struct ir* src, int srcsize, int destsize, int opcode)
{ {
switch (src->size) if (srcsize == 1)
{ {
case 1: opcode += 0; break; if ((opcode == IR_FROMSI) || (opcode == IR_FROMSL))
case 2: opcode += 1; break; {
case 4: opcode += 2; break; src = new_ir1(
case 8: opcode += 3; break; IR_EXTENDB, EM_wordsize,
default: src
fatal("can't convert from things of size %d", src->size); );
}
srcsize = EM_wordsize;
} }
if ((srcsize == 2) && (srcsize != EM_wordsize))
{
if ((opcode == IR_FROMSI) || (opcode == IR_FROMSL))
{
src = new_ir1(
IR_EXTENDH, EM_wordsize,
src
);
}
srcsize = EM_wordsize;
}
if (src->size == EM_wordsize)
{}
else if (src->size == (2*EM_wordsize))
opcode++;
else
fatal("can't convert from %d to %d", src->size, destsize);
return return
new_ir1( new_ir1(
opcode, destsize, opcode, destsize,
@ -153,15 +181,12 @@ static struct ir* convert(struct ir* src, int destsize, int opcode)
static struct ir* compare(struct ir* left, struct ir* right, static struct ir* compare(struct ir* left, struct ir* right,
int size, int opcode) int size, int opcode)
{ {
switch (size) if (size == EM_wordsize)
{ {}
case 1: opcode += 0; break; else if (size == (2*EM_wordsize))
case 2: opcode += 1; break; opcode++;
case 4: opcode += 2; break; else
case 8: opcode += 3; break; fatal("can't compare things of size %d", size);
default:
fatal("can't compare things of size %d", size);
}
return return
new_ir2( new_ir2(
@ -170,6 +195,66 @@ static struct ir* compare(struct ir* left, struct ir* right,
); );
} }
static struct ir* store(int size, struct ir* address, int offset, struct ir* value)
{
int opcode;
if (size == 1)
{
opcode = IR_STOREB;
size = EM_wordsize;
}
else if ((size < EM_wordsize) && (size == 2))
{
opcode = IR_STOREH;
size = EM_wordsize;
}
else
opcode = IR_STORE;
if (offset > 0)
address = new_ir2(
IR_ADD, EM_pointersize,
address, new_wordir(offset)
);
return
new_ir2(
opcode, size,
address, value
);
}
static struct ir* load(int size, struct ir* address, int offset)
{
int opcode;
if (size == 1)
{
opcode = IR_LOADB;
size = EM_wordsize;
}
else if ((size < EM_wordsize) && (size == 2))
{
opcode = IR_LOADH;
size = EM_wordsize;
}
else
opcode = IR_LOAD;
if (offset > 0)
address = new_ir2(
IR_ADD, EM_pointersize,
address, new_wordir(offset)
);
return
new_ir1(
opcode, size,
address
);
}
static struct ir* tristate_compare(int size, int opcode) static struct ir* tristate_compare(int size, int opcode)
{ {
struct ir* right = pop(size); struct ir* right = pop(size);
@ -197,7 +282,7 @@ static void simple_convert(int opcode)
value = pop(srcsize->u.ivalue); value = pop(srcsize->u.ivalue);
push( push(
convert(value, destsize->u.ivalue, opcode) convert(value, srcsize->u.ivalue, destsize->u.ivalue, opcode)
); );
} }
@ -212,7 +297,7 @@ static void simple_branch2(int opcode, int size,
appendir( appendir(
new_ir2( new_ir2(
irop, 0, irop, 0,
compare(left, right, size, IR_COMPARES1), compare(left, right, size, IR_COMPARESI),
new_ir2( new_ir2(
IR_PAIR, 0, IR_PAIR, 0,
new_bbir(truebb), new_bbir(truebb),
@ -238,7 +323,7 @@ static void simple_test(int size, int irop)
push( push(
new_ir1( new_ir1(
irop, EM_wordsize, irop, EM_wordsize,
tristate_compare0(size, IR_COMPARES1) tristate_compare0(size, IR_COMPARESI)
) )
); );
} }
@ -273,16 +358,16 @@ static void insn_simple(int opcode)
break; break;
} }
case op_cii: simple_convert(IR_CII1); break; case op_cii: simple_convert(IR_FROMSI); break;
case op_ciu: simple_convert(IR_CIU1); break; case op_ciu: simple_convert(IR_FROMSI); break;
case op_cui: simple_convert(IR_CUI1); break; case op_cui: simple_convert(IR_FROMUI); break;
case op_cfi: simple_convert(IR_CFI1); break; case op_cfi: simple_convert(IR_FROMF); break;
case op_cif: simple_convert(IR_CIF1); break; case op_cif: simple_convert(IR_FROMSI); break;
case op_cff: simple_convert(IR_CFF1); break; case op_cff: simple_convert(IR_FROMF); break;
case op_cmp: case op_cmp:
push( push(
tristate_compare(EM_pointersize, IR_COMPAREU1) tristate_compare(EM_pointersize, IR_COMPAREUI)
); );
break; break;
@ -468,14 +553,12 @@ static struct ir* extract_block_refs(struct basicblock* bb)
static void change_by(struct ir* address, int amount) static void change_by(struct ir* address, int amount)
{ {
appendir( appendir(
new_ir2( store(
IR_STORE, EM_wordsize, EM_wordsize, address, 0,
address,
new_ir2( new_ir2(
IR_ADD, EM_wordsize, IR_ADD, EM_wordsize,
new_ir1( load(
IR_LOAD, EM_wordsize, EM_wordsize, address, 0
address
), ),
new_wordir(amount) new_wordir(amount)
) )
@ -529,33 +612,33 @@ static void insn_ivalue(int opcode, arith value)
case op_ngf: simple_alu1(opcode, value, IR_NEGF); break; case op_ngf: simple_alu1(opcode, value, IR_NEGF); break;
case op_cmu: /* fall through */ case op_cmu: /* fall through */
case op_cms: push(tristate_compare(value, IR_COMPAREU1)); break; case op_cms: push(tristate_compare(value, IR_COMPAREUI)); break;
case op_cmi: push(tristate_compare(value, IR_COMPARES1)); break; case op_cmi: push(tristate_compare(value, IR_COMPARESI)); break;
case op_cmf: push(tristate_compare(value, IR_COMPAREF1)); break; case op_cmf: push(tristate_compare(value, IR_COMPAREF)); break;
case op_lol: case op_lol:
push( push(
new_ir1( load(
IR_LOAD, EM_wordsize, EM_wordsize,
new_localir(value) new_localir(value), 0
) )
); );
break; break;
case op_ldl: case op_ldl:
push( push(
new_ir1( load(
IR_LOAD, EM_wordsize*2, EM_wordsize*2,
new_localir(value) new_localir(value), 0
) )
); );
break; break;
case op_stl: case op_stl:
appendir( appendir(
new_ir2( store(
IR_STORE, EM_wordsize, EM_wordsize,
new_localir(value), new_localir(value), 0,
pop(EM_wordsize) pop(EM_wordsize)
) )
); );
@ -563,9 +646,9 @@ static void insn_ivalue(int opcode, arith value)
case op_sdl: case op_sdl:
appendir( appendir(
new_ir2( store(
IR_STORE, EM_wordsize*2, EM_wordsize*2,
new_localir(value), new_localir(value), 0,
pop(EM_wordsize*2) pop(EM_wordsize*2)
) )
); );
@ -579,24 +662,24 @@ static void insn_ivalue(int opcode, arith value)
case op_lil: case op_lil:
push( push(
new_ir1( load(
IR_LOAD, EM_wordsize, EM_wordsize,
new_ir1( load(
IR_LOAD, EM_pointersize, EM_pointersize,
new_localir(value) new_localir(value), 0
) ), 0
) )
); );
break; break;
case op_sil: case op_sil:
appendir( appendir(
new_ir2( store(
IR_STORE, EM_wordsize, EM_wordsize,
new_ir1( load(
IR_LOAD, EM_pointersize, EM_pointersize,
new_localir(value) new_localir(value), 0
), ), 0,
pop(EM_wordsize) pop(EM_wordsize)
) )
); );
@ -612,9 +695,9 @@ static void insn_ivalue(int opcode, arith value)
case op_zrl: case op_zrl:
appendir( appendir(
new_ir2( store(
IR_STORE, EM_wordsize, EM_wordsize,
new_localir(value), new_localir(value), 0,
new_wordir(0) new_wordir(0)
) )
); );
@ -630,26 +713,18 @@ static void insn_ivalue(int opcode, arith value)
case op_loe: case op_loe:
push( push(
new_ir1( load(
IR_LOAD, EM_wordsize, EM_wordsize,
new_ir2( new_labelir(".hol0"), value
IR_ADD, EM_pointersize,
new_labelir(".hol0"),
new_wordir(value)
)
) )
); );
break; break;
case op_ste: case op_ste:
appendir( appendir(
new_ir2( store(
IR_STORE, EM_wordsize, EM_wordsize,
new_ir2( new_labelir(".hol0"), value,
IR_ADD, EM_pointersize,
new_labelir(".hol0"),
new_wordir(value)
),
pop(EM_wordsize) pop(EM_wordsize)
) )
); );
@ -657,13 +732,9 @@ static void insn_ivalue(int opcode, arith value)
case op_zre: case op_zre:
appendir( appendir(
new_ir2( store(
IR_STORE, EM_wordsize, EM_wordsize,
new_ir2( new_labelir(".hol0"), value,
IR_ADD, EM_pointersize,
new_labelir(".hol0"),
new_wordir(value)
),
new_wordir(0) new_wordir(0)
) )
); );
@ -694,9 +765,9 @@ static void insn_ivalue(int opcode, arith value)
s = value; s = value;
push( push(
new_ir1( load(
IR_LOAD, s, s,
ptradd(ptr, offset) ptr, offset
) )
); );
@ -713,13 +784,9 @@ static void insn_ivalue(int opcode, arith value)
struct ir* ptr = pop(EM_pointersize); struct ir* ptr = pop(EM_pointersize);
push( push(
new_ir1( load(
IR_LOAD, EM_wordsize, EM_wordsize,
new_ir2( ptr, value
IR_ADD, EM_pointersize,
ptr,
new_wordir(value)
)
) )
); );
break; break;
@ -731,9 +798,10 @@ static void insn_ivalue(int opcode, arith value)
struct ir* val = pop(value); struct ir* val = pop(value);
appendir( appendir(
new_ir2( store(
IR_STORE, value, value,
ptr, val ptr, 0,
val
) )
); );
break; break;
@ -745,13 +813,9 @@ static void insn_ivalue(int opcode, arith value)
struct ir* val = pop(EM_wordsize); struct ir* val = pop(EM_wordsize);
appendir( appendir(
new_ir2( store(
IR_STORE, EM_wordsize, EM_wordsize,
new_ir2( ptr, value,
IR_ADD, EM_pointersize,
ptr,
new_wordir(value)
),
val val
) )
); );
@ -764,7 +828,7 @@ static void insn_ivalue(int opcode, arith value)
struct ir* ptr = pop(EM_pointersize); struct ir* ptr = pop(EM_pointersize);
if (value != EM_pointersize) if (value != EM_pointersize)
off = convert(off, EM_pointersize, IR_CII1); off = convert(off, value, EM_pointersize, IR_FROMUI);
push( push(
new_ir2( new_ir2(
@ -801,7 +865,7 @@ static void insn_ivalue(int opcode, arith value)
); );
if (value != EM_pointersize) if (value != EM_pointersize)
delta = convert(delta, value, IR_CII1); delta = convert(delta, EM_pointersize, value, IR_FROMUI);
push(delta); push(delta);
break; break;

View file

@ -6,6 +6,7 @@
#include <stdint.h> #include <stdint.h>
#include <limits.h> #include <limits.h>
#include "iburg.h" #include "iburg.h"
#include "astring.h"
#define YYDEBUG 1 #define YYDEBUG 1
@ -55,8 +56,9 @@ extern int yylex(void);
%type <rule> pattern %type <rule> pattern
%type <rule> pattern_constraints %type <rule> pattern_constraints
%type <rule> pattern_emit %type <rule> pattern_emit
%type <stringlist> aliases; %type <string> nodename
%type <stringlist> names; %type <stringlist> aliases
%type <stringlist> names
%type <stringlist> qfragments %type <stringlist> qfragments
%type <terminfo> terminfo %type <terminfo> terminfo
%type <tree> rhs %type <tree> rhs
@ -126,10 +128,15 @@ rhs
; ;
terminfo terminfo
: ID { $$.name = $1; } : nodename { $$.name = $1; }
| '(' ID ')' ID { $$.attr = $2; $$.name = $4; } | '(' ID ')' nodename { $$.attr = $2; $$.name = $4; }
| ID ':' ID { $$.label = $1; $$.name = $3; } | ID ':' nodename { $$.label = $1; $$.name = $3; }
| ID ':' '(' ID ')' ID { $$.label = $1; $$.attr = $4; $$.name = $6; } | ID ':' '(' ID ')' nodename { $$.label = $1; $$.attr = $4; $$.name = $6; }
;
nodename
: ID { $$ = $1; }
| ID '.' ID { $$ = aprintf("%s.%s", $1, $3); }
; ;
pattern_emit pattern_emit

View file

@ -151,14 +151,20 @@ int main(int argc, char* argv[])
{ {
const static struct terminfo reg = { "reg", NULL, "" }; const static struct terminfo reg = { "reg", NULL, "" };
const static struct terminfo REG = { "REG", NULL, NULL }; const static struct terminfo REG = { "REG", NULL, NULL };
const static struct terminfo NOP = { "NOP", NULL, NULL }; const static struct terminfo NOPI = { "NOP.I", NULL, NULL };
const static struct terminfo NOPF = { "NOP.F", NULL, NULL };
const static struct terminfo NOPL = { "NOP.L", NULL, NULL };
const static struct terminfo NOPD = { "NOP.D", NULL, NULL };
const static struct terminfo RET = { "RET", NULL, NULL }; const static struct terminfo RET = { "RET", NULL, NULL };
nonterm("reg", true); nonterm("reg", true);
rule(NULL, tree(&reg, NULL, NULL))->cost = 1; rule(NULL, tree(&reg, NULL, NULL))->cost = 1;
rule(&reg, tree(&REG, NULL, NULL))->cost = 1; rule(&reg, tree(&REG, NULL, NULL))->cost = 1;
rule(&reg, tree(&NOP, tree(&reg, NULL, NULL), NULL))->cost = 1; rule(&reg, tree(&NOPI, tree(&reg, NULL, NULL), NULL))->cost = 1;
rule(&reg, tree(&NOPF, tree(&reg, NULL, NULL), NULL))->cost = 1;
rule(&reg, tree(&NOPL, tree(&reg, NULL, NULL), NULL))->cost = 1;
rule(&reg, tree(&NOPD, tree(&reg, NULL, NULL), NULL))->cost = 1;
rule(NULL, tree(&RET, NULL, NULL))->cost = 1; rule(NULL, tree(&RET, NULL, NULL))->cost = 1;
} }
@ -195,10 +201,10 @@ int main(int argc, char* argv[])
return errcnt > 0; return errcnt > 0;
} }
static void registerterminal(const struct ir_data* data, int iropcode, int size) static void registerterminal(const struct ir_data* data, int iropcode, char type)
{ {
const char* s = (size == 0) ? data->name : aprintf("%s%d", data->name, size); const char* s = (type == 0) ? data->name : aprintf("%s.%c", data->name, type);
int esn = ir_to_esn(iropcode, size); int esn = ir_to_esn(iropcode, type);
term(s, esn); term(s, esn);
} }
@ -209,15 +215,11 @@ static void registerterminals(void)
for (i=0; i<IR__COUNT; i++) for (i=0; i<IR__COUNT; i++)
{ {
if (ir_data[i].flags & IRF_SIZED) registerterminal(&ir_data[i], i, 'I');
{ registerterminal(&ir_data[i], i, 'F');
registerterminal(&ir_data[i], i, 1); registerterminal(&ir_data[i], i, 'L');
registerterminal(&ir_data[i], i, 2); registerterminal(&ir_data[i], i, 'D');
registerterminal(&ir_data[i], i, 4); registerterminal(&ir_data[i], i, 0);
registerterminal(&ir_data[i], i, 8);
}
else
registerterminal(&ir_data[i], i, 0);
} }
} }

View file

@ -1,7 +1,3 @@
# Flags:
# S: has size (use in CONST1, CONST2, CONST4, CONST8 forms)
# V: has no size (use in JUMP, CJUMP, RET forms)
#
# Types: # Types:
# #
# I, F, L, D: int, float, long, double # I, F, L, D: int, float, long, double
@ -13,7 +9,7 @@
S ?=.. CONST # must be followed by float form S ?=.. CONST # must be followed by float form
S ?=.. CONSTF S ?=.. CONSTF
V ?=.. REG V ?=.. REG
V ?=?. NOP S ?=?. NOP
S I=.. LABEL S I=.. LABEL
S I=.. BLOCK S I=.. BLOCK
V ?=.. PAIR V ?=.. PAIR
@ -24,13 +20,14 @@ V ?=.. PHI
# Magic stack operations # Magic stack operations
S ?=?. PUSH S ?=?. PUSH
S ?=.. POP S ?=.. POP
S ?=.. POPF
# Memory operations # Memory operations
S ?=I. LOAD # must be followed by float form S ?=I. LOAD
S f=I. LOADF S I=I. LOADB
S I=I. LOADH
S ?=I? STORE S ?=I? STORE
S ?=If STOREF S ?=I? STOREB
S ?=I? STOREH
# Arithemetic operations # Arithemetic operations
S i=ii ADD S i=ii ADD
@ -59,58 +56,38 @@ S i=ii LSR
# Bitwise conversions # Bitwise conversions
# (Remember, these don't change the value, merely move it) # (Remember, these don't change the value, merely move it)
S i=f. COPYF # (order is important here; the 8-byte version of each must immediate succeed
S f=i. COPYI # the 4-byte version)
S F=I. COPYI
S I=F. COPYF
S D=L. COPYL
S L=D. COPYD
# Semantic conversions # Semantic conversions
S F=D. D2F # (order is important here; the 8-byte version of each must immediate succeed
S D=F. F2D # the 4-byte version)
S ?=I. FROMUI
S ?=L. FROMUL
S ?=I. FROMSI
S ?=L. FROMSL
S ?=F. FROMF
S ?=D. FROMD
S I=I. CII1 # The H versions are only used if wordsize > 2
S I=I. CII2 S I=I. EXTENDB
S I=I. CII4 S I=I. EXTENDH
S L=L. CII8 S I=I. TRUNCATEB
S I=I. TRUNCATEH
S I=I. CIU1
S I=I. CIU2
S I=I. CIU4
S L=L. CIU8
S I=I. CUI1
S I=I. CUI2
S I=I. CUI4
S L=L. CUI8
S I=F. CFI1
S I=F. CFI2
S I=F. CFI4
S L=D. CFI8
S I=F. CIF1
S I=F. CIF2
S I=F. CIF4
S L=D. CIF8
S F=F. CFF1
S F=F. CFF2
S F=F. CFF4
S D=D. CFF8
# Tristate comparisons # Tristate comparisons
S I=II COMPARES1 # (order is important here; the 8-byte version of each must immediate succeed
S I=II COMPARES2 # the 4-byte version)
S I=II COMPARES4 S I=II COMPARESI
S I=LL COMPARES8 S I=LL COMPARESL
S I=II COMPAREUI
S I=II COMPAREU1 S I=LL COMPAREUL
S I=II COMPAREU2 S I=FF COMPAREF
S I=II COMPAREU4 S I=DD COMPARED
S I=LL COMPAREU8
S I=FF COMPAREF1
S I=FF COMPAREF2
S I=FF COMPAREF4
S I=DD COMPAREF8
# Tristate to boolean conversion # Tristate to boolean conversion
S I=I. IFEQ S I=I. IFEQ

View file

@ -3,14 +3,14 @@
/* Excruciating macro which packs ir opcodes and sizes into an int for iburg's benefit. /* Excruciating macro which packs ir opcodes and sizes into an int for iburg's benefit.
* *
* Sizes are mapped as: 0=1, 1=1, 2=2, 4=3, 8=4. * Types are mapped to: I=1, F=2, L=3, D=4
*/ */
#define ir_to_esn(iropcode, size) \ #define ir_to_esn(iropcode, type) \
((iropcode)*4 + \ ((iropcode)*5 + \
(((size) == 4) ? 2 : \ (((type) == 'I') ? 1 : \
((size) == 8) ? 3 : \ ((type) == 'F') ? 2 : \
((size) == 0) ? 0 : \ ((type) == 'L') ? 3 : \
(size-1))) ((type) == 'D') ? 4 : 0))
#define STATE_TYPE void* #define STATE_TYPE void*