From: David Given Date: Sun, 23 Oct 2016 19:54:14 +0000 (+0200) Subject: Massive change to how IR types are handled; we use the type code for matching X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=abd0cedd61aed515f22c75c0e1f85213d377494d;p=ack.git Massive change to how IR types are handled; we use the type code for matching rather than the size. Much cleaner and simpler. --- diff --git a/mach/powerpc/mcg/platform.c b/mach/powerpc/mcg/platform.c index 2b22ec1f3..664ed3848 100644 --- a/mach/powerpc/mcg/platform.c +++ b/mach/powerpc/mcg/platform.c @@ -99,7 +99,7 @@ struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg* { struct hop* hop = new_hop(bb, NULL); 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)) { @@ -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); break; - case burm_pair_ATTR: + case burm_long_ATTR: hop_add_insel(hop, "stwu %0H, -4(sp)", src); hop_add_insel(hop, "stwu %1H, -4(sp)", src); 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); break; - case burm_pair_ATTR: + case burm_long_ATTR: hop_add_insel(hop, "lwz %0H, 4(sp)", dest); hop_add_insel(hop, "lwz %1H, 0(sp)", dest); break; @@ -160,7 +160,7 @@ struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg* break; case burm_double_ATTR: - case burm_pair_ATTR: + case burm_long_ATTR: hop_add_insel(hop, "addi sp, sp, 8"); 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); break; - case burm_pair_ATTR: + case burm_long_ATTR: hop_add_insel(hop, "mr %0H, %0H", dest, src); hop_add_insel(hop, "mr %1H, %1H", dest, src); break; diff --git a/mach/powerpc/mcg/table b/mach/powerpc/mcg/table index 8a87e079d..2c3565a73 100644 --- a/mach/powerpc/mcg/table +++ b/mach/powerpc/mcg/table @@ -38,21 +38,21 @@ REGISTERS r14 bytes4! int!; r13 bytes4! int!; - r11r12 named("r11", "r12") aliases(r11, r12) bytes8! pair! volatile; - r9r10 named("r9", "r10") aliases(r9, r10) bytes8! pair! volatile; - r7r8 named("r7", "r8") aliases(r7, r8) bytes8! pair! volatile; - r5r6 named("r5", "r6") aliases(r6, r6) bytes8! pair! volatile; - r3r4 named("r3", "r4") aliases(r3, r4) bytes8! pair! volatile pret; - - r29r30 named("r29", "r30") aliases(r29, r30) bytes8! pair!; - r27r28 named("r27", "r28") aliases(r27, r28) bytes8! pair!; - r25r26 named("r25", "r26") aliases(r25, r26) bytes8! pair!; - r23r24 named("r23", "r24") aliases(r23, r24) bytes8! pair!; - r21r22 named("r21", "r22") aliases(r21, r22) bytes8! pair!; - r19r20 named("r19", "r20") aliases(r19, r20) bytes8! pair!; - r17r18 named("r17", "r18") aliases(r17, r18) bytes8! pair!; - r15r16 named("r15", "r16") aliases(r15, r16) bytes8! pair!; - r13r14 named("r13", "r14") aliases(r13, r14) bytes8! pair!; + r11r12 named("r11", "r12") aliases(r11, r12) bytes8! long! volatile; + r9r10 named("r9", "r10") aliases(r9, r10) bytes8! long! volatile; + r7r8 named("r7", "r8") aliases(r7, r8) bytes8! long! volatile; + r5r6 named("r5", "r6") aliases(r6, r6) bytes8! long! volatile; + r3r4 named("r3", "r4") aliases(r3, r4) bytes8! long! volatile pret; + + r29r30 named("r29", "r30") aliases(r29, r30) bytes8! long!; + r27r28 named("r27", "r28") aliases(r27, r28) bytes8! long!; + r25r26 named("r25", "r26") aliases(r25, r26) bytes8! long!; + r23r24 named("r23", "r24") aliases(r23, r24) bytes8! long!; + r21r22 named("r21", "r22") aliases(r21, r22) bytes8! long!; + r19r20 named("r19", "r20") aliases(r19, r20) bytes8! long!; + r17r18 named("r17", "r18") aliases(r17, r18) bytes8! long!; + r15r16 named("r15", "r16") aliases(r15, r16) bytes8! long!; + r13r14 named("r13", "r14") aliases(r13, r14) bytes8! long!; f14 bytes4! float! volatile; f13 bytes4! float! volatile; @@ -142,73 +142,90 @@ PATTERNS /* Special */ - PAIR(BLOCK4, BLOCK4); + PAIR(BLOCK.I, BLOCK.I); /* Miscellaneous special things */ - PUSH4(in:(int)reg) + PUSH.I(in:(int)reg) emit "stwu %in, -4(sp)" cost 4; - PUSH8(in:(pair)reg) + PUSH.L(in:(long)reg) emit "stwu %in.0, -4(sp)" emit "stwu %in.1, -4(sp)" 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 "addi sp, sp, 4" cost 8; - out:(pair)reg = POP8 + out:(long)reg = POP.L emit "lwz %out.0, 4(sp)" emit "lwz %out.1, 0(sp)" emit "addi sp, sp, 8" cost 12; - out:(float)reg = POPF4 + out:(float)reg = POP.F emit "lfs %out, 0(sp)" emit "addi sp, sp, 4" cost 8; - SETRET4(in:(ret)reg) + SETRET.I(in:(ret)reg) emit "! setret4" cost 1; - SETRET8(in:(pret)reg) + SETRET.L(in:(pret)reg) emit "! setret8" cost 1; - STACKADJUST4(delta:CONST4) + STACKADJUST.I(delta:CONST.I) when signed_constant(%delta, 16) emit "addi sp, sp, $delta" cost 4; - STACKADJUST4(in:(int)reg) + STACKADJUST.I(in:(int)reg) emit "add sp, sp, %in" cost 4; - out:(int)reg = GETFP4 + out:(int)reg = GETFP.I emit "mr %out, fp" cost 4; - out:(int)reg = FPTOARGS4(GETFP4) + out:(int)reg = FPTOARGS.I(GETFP.I) emit "addi %out, fp, 8" cost 4; - out:(int)reg = FPTOARGS4(in:(int)reg) + out:(int)reg = FPTOARGS.I(in:(int)reg) emit "addi %out, %in, 8" cost 4; - out:(int)reg = GETSP4 + out:(int)reg = GETSP.I emit "mr %out, sp" cost 4; - SETSP4(in:(int)reg) + SETSP.I(in:(int)reg) emit "mr sp, %in" 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 */ - STORE8(addr:address, value:(pair)reg) + STORE.L(addr:address, value:(long)reg) emit "stw %value.0, 4+%addr" emit "stw %value.1, 0+%addr" cost 4; - STORE4(addr:address, value:(int)reg) + STORE.I(addr:address, value:(int)reg) emit "stw %value, %addr" cost 4; - STORE2(addr:address, value:(int)ushortX) + STOREH.I(addr:address, value:(int)ushortX) emit "sth %value, %addr" 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" 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" 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" cost 4; /* Loads */ - out:(int)reg = LOAD4(addr:address) + out:(int)reg = LOAD.I(addr:address) emit "lwz %out, %addr" cost 4; - out:(pair)reg = LOAD8(addr:address) + out:(long)reg = LOAD.L(addr:address) emit "lwz %out.0, 4+%addr" emit "lwz %out.1, 0+%addr" 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" cost 4; - out:(int)ubyte0 = LOAD1(addr:address) + out:(int)ubyte0 = LOADB.I(addr:address) emit "lbz %out, %addr" cost 4; @@ -302,6 +327,38 @@ PATTERNS emit "! reg -> ushortX" 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 */ out:(int)ubyte0 = CIU14(in:(int)ubyte0) @@ -348,22 +405,23 @@ PATTERNS out:(int)reg = CII24(in:(int)ushortX) emit "extsh %out, %in" cost 4; +#endif /* Locals */ - out:(int)reg = in:LOCAL4 + out:(int)reg = in:LOCAL.I emit "addi %out, fp, $in" cost 4; - address = in:LOCAL4 + address = in:LOCAL.I emit "$in(fp)"; /* Memory addressing modes */ - address = ADD4(addr:(int)reg, offset:CONST4) + address = ADD.I(addr:(int)reg, offset:CONST.I) when signed_constant(%offset, 16) emit "$offset(%addr)"; @@ -374,59 +432,59 @@ PATTERNS /* Branches */ - JUMP(addr:BLOCK4) + JUMP(addr:BLOCK.I) emit "b $addr" 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 "b $false" 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 "b $false" 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 "b $false" cost 8; - CALL1(dest:LABEL4) + CALL(dest:LABEL.I) with corrupted(volatile) emit "bl $dest" cost 4; - out:(ret)reg = CALL4(dest:LABEL4) + out:(ret)reg = CALL.I(dest:LABEL.I) with corrupted(volatile) emit "bl $dest" cost 4; - out:(pret)reg = CALL8(dest:LABEL4) + out:(pret)reg = CALL.L(dest:LABEL.I) with corrupted(volatile) emit "bl $dest" cost 4; - CALL1(dest:(int)reg) + CALL(dest:(int)reg) with corrupted(volatile) emit "mtspr ctr, %dest" emit "bcctrl 20, 0, 0" cost 8; - out:(ret)reg = CALL4(dest:(int)reg) + out:(ret)reg = CALL.I(dest:(int)reg) with corrupted(volatile) emit "mtspr ctr, %dest" emit "bcctrl 20, 0, 0" cost 8; - out:(pret)reg = CALL8(dest:(int)reg) + out:(pret)reg = CALL.L(dest:(int)reg) with corrupted(volatile) emit "mtspr ctr, %dest" emit "bcctrl 20, 0, 0" cost 8; - JUMP(dest:LABEL4) + JUMP(dest:LABEL.I) emit "b $dest" cost 4; @@ -434,40 +492,40 @@ PATTERNS /* 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" 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) emit "cmpi %cr, 0, %left, $right" 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" 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) emit "cmpli %cr, 0, %left, $right" 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) with %out == %in - emit "! COMPARES(cr, 0)" + emit "! COMPARESI.I(cr, 0)" cost 4; /* Booleans */ - out:(int)reg = IFEQ4(in:(cr)cr) + out:(int)reg = IFEQ.I(in:(cr)cr) emit "mfcr %out" /* get cr0 */ emit "rlwinm %out, %out, [32-2], 2, 31" /* extract just EQ */ 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 "rlwinm %out, %out, [32-5], 5, 31" /* if 32, return 1, otherwise 0 */ cost 8; @@ -476,6 +534,7 @@ PATTERNS /* Conversions */ +#if 0 out:(int)reg = CIU44(in:(int)reg) with %out == %in emit "! ciu44" @@ -485,7 +544,7 @@ PATTERNS with %out == %in emit "! cui44" cost 4; - +#endif /* ALU operations */ @@ -495,13 +554,13 @@ PATTERNS cost 4; \ #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) \ emit instr " %out, %left, $right" \ cost 4; \ #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) \ emit instr " %out, %right, $left" \ cost 4; \ @@ -510,66 +569,66 @@ PATTERNS ALUC(name, instr) \ ALUC_reversed(name, instr) - ALUR(ADD4, "add") - ALUCC(ADD4, "addi") + ALUR(ADD.I, "add") + 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" 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]" 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 "mullw %out, %out, %right" emit "subf %out, %out, %left" 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 "mullw %out, %out, %right" emit "subf %out, %out, %left" cost 12; - ALUR(MUL4, "mullw") - ALUCC(MUL4, "mulli") + ALUR(MUL.I, "mullw") + ALUCC(MUL.I, "mulli") - ALUR(DIV4, "divw") - ALUR(DIVU4, "divwu") + ALUR(DIV.I, "divw") + 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" cost 4; - out:(int)reg = NOT4(left:(int)reg) + out:(int)reg = NOT.I(left:(int)reg) emit "cntlzw %out, %left" emit "rlwinm %out, %out, 32-5, 5, 31" cost 8; - ALUR(AND4, "and") - ALUCC(AND4, "andi.") + ALUR(AND.I, "and") + ALUCC(AND.I, "andi.") - ALUR(OR4, "or") - ALUCC(OR4, "ori") + ALUR(OR.I, "or") + ALUCC(OR.I, "ori") - ALUR(EOR4, "xor") - ALUCC(EOR4, "xori") + ALUR(EOR.I, "xor") + ALUCC(EOR.I, "xori") - out:(int)reg = value:LABEL4 + out:(int)reg = value:LABEL.I emit "la %out, $value" cost 4; - out:(int)reg = value:BLOCK4 + out:(int)reg = value:BLOCK.I emit "la %out, $value" cost 4; - out:(int)reg = value:CONST4 + out:(int)reg = value:CONST.I emit "li %out, $value" cost 8; @@ -586,46 +645,47 @@ PATTERNS emit instr " %out, %left, %right" \ cost 4; \ - out:(float)reg = LOADF4(addr:address) + out:(float)reg = LOAD.F(addr:address) emit "lfs %out, %addr" cost 4; - out:(double)reg = LOADF8(addr:address) + out:(double)reg = LOAD.D(addr:address) emit "lfd %out, %addr" cost 4; - out:(float)reg = value:CONSTF4 + out:(float)reg = value:CONST.F emit "lfs %out, address-containing-$value" cost 8; - FPU4R(ADDF4, "fadds") - FPU8R(ADDF8, "fadd") + FPU4R(ADDF.F, "fadds") + FPU8R(ADDF.D, "fadd") - FPU4R(SUBF4, "fsubs") - FPU8R(SUBF8, "fsub") + FPU4R(SUBF.F, "fsubs") + FPU8R(SUBF.D, "fsub") - FPU4R(MULF4, "fmuls") - FPU8R(MULF8, "fmul") + FPU4R(MULF.F, "fmuls") + FPU8R(MULF.D, "fmul") - FPU4R(DIVF4, "fdivs") - FPU8R(DIVF8, "fdiv") + FPU4R(DIVF.F, "fdivs") + FPU8R(DIVF.D, "fdiv") - out:(float)reg = NEGF4(left:(float)reg) + out:(float)reg = NEGF.F(left:(float)reg) emit "fneg %out, %left" cost 4; - out:(double)reg = NEGF8(left:(double)reg) + out:(double)reg = NEGF.D(left:(double)reg) emit "fneg %out, %left" 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" 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" cost 4; + #if 0 out:(ret)reg = CFI44(val:(fret)reg) with corrupted(volatile) emit "bl .cfi44" @@ -653,6 +713,7 @@ PATTERNS out:(double)reg = CFF48(val:(float)reg) emit "fmr %out, %val" cost 1; + #endif /* vim: set sw=4 ts=4 expandtab : */ diff --git a/mach/proto/mcg/pass_convertstackops.c b/mach/proto/mcg/pass_convertstackops.c index a8968c22f..59290d376 100644 --- a/mach/proto/mcg/pass_convertstackops.c +++ b/mach/proto/mcg/pass_convertstackops.c @@ -89,7 +89,6 @@ static void convert_block(struct basicblock* bb) { struct ir* ir = pushes.item[i].right; ir->opcode = IR_NOP; - ir->size = 0; } for (i=0; ilabel) { - case ir_to_esn(IR_REG, 1): - case ir_to_esn(IR_REG, 2): - case ir_to_esn(IR_REG, 4): - case ir_to_esn(IR_REG, 8): + case ir_to_esn(IR_REG, 0): current_hop->output = node->ir->result; 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; break; } @@ -241,7 +241,7 @@ static struct burm_node* build_shadow_tree(struct ir* root, struct ir* ir) 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) node->left = build_shadow_tree(root, ir->left); diff --git a/mach/proto/mcg/pass_ssa.c b/mach/proto/mcg/pass_ssa.c index 99f4928ef..260ad9294 100644 --- a/mach/proto/mcg/pass_ssa.c +++ b/mach/proto/mcg/pass_ssa.c @@ -63,11 +63,10 @@ static bool rewrite_loads_cb(struct ir* ir, void* user) if (ir->right && is_local(ir->right)) 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)) { ir->opcode = IR_NOP; - ir->size = 0; ir->left = definition; ir->right = NULL; } @@ -108,7 +107,6 @@ static void recursively_rewrite_tree(struct basicblock* bb) if (ir->opcode == IR_STORE) { ir->opcode = IR_NOP; - ir->size = 0; ir->left = ir->right; ir->right = NULL; } diff --git a/mach/proto/mcg/pass_typeinference.c b/mach/proto/mcg/pass_typeinference.c index d330152ef..90a0ead1a 100644 --- a/mach/proto/mcg/pass_typeinference.c +++ b/mach/proto/mcg/pass_typeinference.c @@ -212,11 +212,11 @@ static struct ir* new_copy(char wanted, char real, struct ir* ir) if ((wanted == 'F') && (real == 'I')) opcode = IR_COPYI; else if ((wanted == 'D') && (real == 'L')) - opcode = IR_COPYI; + opcode = IR_COPYL; else if ((wanted == 'I') && (real == 'F')) opcode = IR_COPYF; else if ((wanted == 'L') && (real == 'D')) - opcode = IR_COPYF; + opcode = IR_COPYD; else fatal("type mismatch: parent IR wanted %c, child IR provided %c", wanted, real); diff --git a/mach/proto/mcg/treebuilder.c b/mach/proto/mcg/treebuilder.c index 4ec1b46e0..b1b235f30 100644 --- a/mach/proto/mcg/treebuilder.c +++ b/mach/proto/mcg/treebuilder.c @@ -6,7 +6,7 @@ static int stackptr; static struct ir* stack[64]; 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 void reset_stack(void) @@ -19,17 +19,22 @@ static void push(struct ir* ir) if (stackptr == sizeof(stack)/sizeof(*stack)) fatal("stack overflow"); +#if 0 /* If we try to push something which is too small, convert it to a word * first. */ if (ir->size < EM_wordsize) - ir = convert(ir, EM_wordsize, IR_CIU1); + ir = convertu(ir, EM_wordsize); +#endif stack[stackptr++] = ir; } static struct ir* pop(int size) { + if (size < EM_wordsize) + size = EM_wordsize; + if (stackptr == 0) { /* 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]; +#if 0 /* If we try to pop something which is smaller than a word, convert it first. */ if (size < EM_wordsize) - ir = convert(ir, size, IR_CIU1); + ir = convertu(ir, size); +#endif if (ir->size != 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); } -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; - case 2: opcode += 1; break; - case 4: opcode += 2; break; - case 8: opcode += 3; break; - default: - fatal("can't convert from things of size %d", src->size); + if ((opcode == IR_FROMSI) || (opcode == IR_FROMSL)) + { + src = new_ir1( + IR_EXTENDB, EM_wordsize, + src + ); + } + 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 new_ir1( 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, int size, int opcode) { - switch (size) - { - case 1: opcode += 0; break; - case 2: opcode += 1; break; - case 4: opcode += 2; break; - case 8: opcode += 3; break; - default: - fatal("can't compare things of size %d", size); - } + if (size == EM_wordsize) + {} + else if (size == (2*EM_wordsize)) + opcode++; + else + fatal("can't compare things of size %d", size); return 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) { struct ir* right = pop(size); @@ -197,7 +282,7 @@ static void simple_convert(int opcode) value = pop(srcsize->u.ivalue); 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( new_ir2( irop, 0, - compare(left, right, size, IR_COMPARES1), + compare(left, right, size, IR_COMPARESI), new_ir2( IR_PAIR, 0, new_bbir(truebb), @@ -238,7 +323,7 @@ static void simple_test(int size, int irop) push( new_ir1( irop, EM_wordsize, - tristate_compare0(size, IR_COMPARES1) + tristate_compare0(size, IR_COMPARESI) ) ); } @@ -273,16 +358,16 @@ static void insn_simple(int opcode) break; } - case op_cii: simple_convert(IR_CII1); break; - case op_ciu: simple_convert(IR_CIU1); break; - case op_cui: simple_convert(IR_CUI1); break; - case op_cfi: simple_convert(IR_CFI1); break; - case op_cif: simple_convert(IR_CIF1); break; - case op_cff: simple_convert(IR_CFF1); break; + case op_cii: simple_convert(IR_FROMSI); break; + case op_ciu: simple_convert(IR_FROMSI); break; + case op_cui: simple_convert(IR_FROMUI); break; + case op_cfi: simple_convert(IR_FROMF); break; + case op_cif: simple_convert(IR_FROMSI); break; + case op_cff: simple_convert(IR_FROMF); break; case op_cmp: push( - tristate_compare(EM_pointersize, IR_COMPAREU1) + tristate_compare(EM_pointersize, IR_COMPAREUI) ); break; @@ -468,14 +553,12 @@ static struct ir* extract_block_refs(struct basicblock* bb) static void change_by(struct ir* address, int amount) { appendir( - new_ir2( - IR_STORE, EM_wordsize, - address, + store( + EM_wordsize, address, 0, new_ir2( IR_ADD, EM_wordsize, - new_ir1( - IR_LOAD, EM_wordsize, - address + load( + EM_wordsize, address, 0 ), 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_cmu: /* fall through */ - case op_cms: push(tristate_compare(value, IR_COMPAREU1)); break; - case op_cmi: push(tristate_compare(value, IR_COMPARES1)); break; - case op_cmf: push(tristate_compare(value, IR_COMPAREF1)); break; + case op_cms: push(tristate_compare(value, IR_COMPAREUI)); break; + case op_cmi: push(tristate_compare(value, IR_COMPARESI)); break; + case op_cmf: push(tristate_compare(value, IR_COMPAREF)); break; case op_lol: push( - new_ir1( - IR_LOAD, EM_wordsize, - new_localir(value) + load( + EM_wordsize, + new_localir(value), 0 ) ); break; case op_ldl: push( - new_ir1( - IR_LOAD, EM_wordsize*2, - new_localir(value) + load( + EM_wordsize*2, + new_localir(value), 0 ) ); break; case op_stl: appendir( - new_ir2( - IR_STORE, EM_wordsize, - new_localir(value), + store( + EM_wordsize, + new_localir(value), 0, pop(EM_wordsize) ) ); @@ -563,9 +646,9 @@ static void insn_ivalue(int opcode, arith value) case op_sdl: appendir( - new_ir2( - IR_STORE, EM_wordsize*2, - new_localir(value), + store( + EM_wordsize*2, + new_localir(value), 0, pop(EM_wordsize*2) ) ); @@ -579,24 +662,24 @@ static void insn_ivalue(int opcode, arith value) case op_lil: push( - new_ir1( - IR_LOAD, EM_wordsize, - new_ir1( - IR_LOAD, EM_pointersize, - new_localir(value) - ) + load( + EM_wordsize, + load( + EM_pointersize, + new_localir(value), 0 + ), 0 ) ); break; case op_sil: appendir( - new_ir2( - IR_STORE, EM_wordsize, - new_ir1( - IR_LOAD, EM_pointersize, - new_localir(value) - ), + store( + EM_wordsize, + load( + EM_pointersize, + new_localir(value), 0 + ), 0, pop(EM_wordsize) ) ); @@ -612,9 +695,9 @@ static void insn_ivalue(int opcode, arith value) case op_zrl: appendir( - new_ir2( - IR_STORE, EM_wordsize, - new_localir(value), + store( + EM_wordsize, + new_localir(value), 0, new_wordir(0) ) ); @@ -630,26 +713,18 @@ static void insn_ivalue(int opcode, arith value) case op_loe: push( - new_ir1( - IR_LOAD, EM_wordsize, - new_ir2( - IR_ADD, EM_pointersize, - new_labelir(".hol0"), - new_wordir(value) - ) + load( + EM_wordsize, + new_labelir(".hol0"), value ) ); break; case op_ste: appendir( - new_ir2( - IR_STORE, EM_wordsize, - new_ir2( - IR_ADD, EM_pointersize, - new_labelir(".hol0"), - new_wordir(value) - ), + store( + EM_wordsize, + new_labelir(".hol0"), value, pop(EM_wordsize) ) ); @@ -657,13 +732,9 @@ static void insn_ivalue(int opcode, arith value) case op_zre: appendir( - new_ir2( - IR_STORE, EM_wordsize, - new_ir2( - IR_ADD, EM_pointersize, - new_labelir(".hol0"), - new_wordir(value) - ), + store( + EM_wordsize, + new_labelir(".hol0"), value, new_wordir(0) ) ); @@ -694,9 +765,9 @@ static void insn_ivalue(int opcode, arith value) s = value; push( - new_ir1( - IR_LOAD, s, - ptradd(ptr, offset) + load( + s, + ptr, offset ) ); @@ -713,13 +784,9 @@ static void insn_ivalue(int opcode, arith value) struct ir* ptr = pop(EM_pointersize); push( - new_ir1( - IR_LOAD, EM_wordsize, - new_ir2( - IR_ADD, EM_pointersize, - ptr, - new_wordir(value) - ) + load( + EM_wordsize, + ptr, value ) ); break; @@ -731,9 +798,10 @@ static void insn_ivalue(int opcode, arith value) struct ir* val = pop(value); appendir( - new_ir2( - IR_STORE, value, - ptr, val + store( + value, + ptr, 0, + val ) ); break; @@ -745,13 +813,9 @@ static void insn_ivalue(int opcode, arith value) struct ir* val = pop(EM_wordsize); appendir( - new_ir2( - IR_STORE, EM_wordsize, - new_ir2( - IR_ADD, EM_pointersize, - ptr, - new_wordir(value) - ), + store( + EM_wordsize, + ptr, value, val ) ); @@ -764,7 +828,7 @@ static void insn_ivalue(int opcode, arith value) struct ir* ptr = pop(EM_pointersize); if (value != EM_pointersize) - off = convert(off, EM_pointersize, IR_CII1); + off = convert(off, value, EM_pointersize, IR_FROMUI); push( new_ir2( @@ -801,7 +865,7 @@ static void insn_ivalue(int opcode, arith value) ); if (value != EM_pointersize) - delta = convert(delta, value, IR_CII1); + delta = convert(delta, EM_pointersize, value, IR_FROMUI); push(delta); break; diff --git a/util/mcgg/gram.y b/util/mcgg/gram.y index 4844da073..691ffcb06 100644 --- a/util/mcgg/gram.y +++ b/util/mcgg/gram.y @@ -6,6 +6,7 @@ #include #include #include "iburg.h" +#include "astring.h" #define YYDEBUG 1 @@ -55,8 +56,9 @@ extern int yylex(void); %type pattern %type pattern_constraints %type pattern_emit -%type aliases; -%type names; +%type nodename +%type aliases +%type names %type qfragments %type terminfo %type rhs @@ -126,10 +128,15 @@ rhs ; terminfo - : ID { $$.name = $1; } - | '(' ID ')' ID { $$.attr = $2; $$.name = $4; } - | ID ':' ID { $$.label = $1; $$.name = $3; } - | ID ':' '(' ID ')' ID { $$.label = $1; $$.attr = $4; $$.name = $6; } + : nodename { $$.name = $1; } + | '(' ID ')' nodename { $$.attr = $2; $$.name = $4; } + | ID ':' nodename { $$.label = $1; $$.name = $3; } + | ID ':' '(' ID ')' nodename { $$.label = $1; $$.attr = $4; $$.name = $6; } + ; + +nodename + : ID { $$ = $1; } + | ID '.' ID { $$ = aprintf("%s.%s", $1, $3); } ; pattern_emit diff --git a/util/mcgg/iburg.c b/util/mcgg/iburg.c index 146f920c3..f45043773 100644 --- a/util/mcgg/iburg.c +++ b/util/mcgg/iburg.c @@ -151,14 +151,20 @@ int main(int argc, char* argv[]) { const static struct terminfo reg = { "reg", 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 }; nonterm("reg", true); rule(NULL, tree(®, NULL, NULL))->cost = 1; rule(®, tree(®, NULL, NULL))->cost = 1; - rule(®, tree(&NOP, tree(®, NULL, NULL), NULL))->cost = 1; + rule(®, tree(&NOPI, tree(®, NULL, NULL), NULL))->cost = 1; + rule(®, tree(&NOPF, tree(®, NULL, NULL), NULL))->cost = 1; + rule(®, tree(&NOPL, tree(®, NULL, NULL), NULL))->cost = 1; + rule(®, tree(&NOPD, tree(®, NULL, 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; } -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); - int esn = ir_to_esn(iropcode, size); + const char* s = (type == 0) ? data->name : aprintf("%s.%c", data->name, type); + int esn = ir_to_esn(iropcode, type); term(s, esn); } @@ -209,15 +215,11 @@ static void registerterminals(void) for (i=0; i 2 +S I=I. EXTENDB +S I=I. EXTENDH +S I=I. TRUNCATEB +S I=I. TRUNCATEH # Tristate comparisons -S I=II COMPARES1 -S I=II COMPARES2 -S I=II COMPARES4 -S I=LL COMPARES8 - -S I=II COMPAREU1 -S I=II COMPAREU2 -S I=II COMPAREU4 -S I=LL COMPAREU8 - -S I=FF COMPAREF1 -S I=FF COMPAREF2 -S I=FF COMPAREF4 -S I=DD COMPAREF8 +# (order is important here; the 8-byte version of each must immediate succeed +# the 4-byte version) +S I=II COMPARESI +S I=LL COMPARESL +S I=II COMPAREUI +S I=LL COMPAREUL +S I=FF COMPAREF +S I=DD COMPARED # Tristate to boolean conversion S I=I. IFEQ diff --git a/util/mcgg/mcgg.h b/util/mcgg/mcgg.h index da0c8b1a1..9b0b876fd 100644 --- a/util/mcgg/mcgg.h +++ b/util/mcgg/mcgg.h @@ -3,14 +3,14 @@ /* 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) \ - ((iropcode)*4 + \ - (((size) == 4) ? 2 : \ - ((size) == 8) ? 3 : \ - ((size) == 0) ? 0 : \ - (size-1))) +#define ir_to_esn(iropcode, type) \ + ((iropcode)*5 + \ + (((type) == 'I') ? 1 : \ + ((type) == 'F') ? 2 : \ + ((type) == 'L') ? 3 : \ + ((type) == 'D') ? 4 : 0)) #define STATE_TYPE void*