f06b51c981
find new registers when evicting values. Input constraints work (they were being ignored before). Various bug fixing so they actually work.
378 lines
7.8 KiB
Plaintext
378 lines
7.8 KiB
Plaintext
REGISTERS
|
|
|
|
/* Registers are allocated top down; the order here is odd in order to make
|
|
* sure that non-volatile registers get allocated from r31 (or f31) down.
|
|
*
|
|
* Attributes ending in an exclamation mark must match exactly when copying
|
|
* a register into another register (e.g. for eviction).
|
|
*/
|
|
|
|
r12 bytes4! int! volatile;
|
|
r11 bytes4! int! volatile;
|
|
r10 bytes4! int! volatile;
|
|
r9 bytes4! int! volatile;
|
|
r8 bytes4! int! volatile;
|
|
r7 bytes4! int! volatile;
|
|
r6 bytes4! int! volatile;
|
|
r5 bytes4! int! volatile;
|
|
r4 bytes4! int! volatile;
|
|
r3 bytes4! int! ret volatile;
|
|
|
|
r31 bytes4! int!;
|
|
r30 bytes4! int!;
|
|
r29 bytes4! int!;
|
|
r28 bytes4! int!;
|
|
r27 bytes4! int!;
|
|
r26 bytes4! int!;
|
|
r25 bytes4! int!;
|
|
r24 bytes4! int!;
|
|
r23 bytes4! int!;
|
|
r22 bytes4! int!;
|
|
r21 bytes4! int!;
|
|
r20 bytes4! int!;
|
|
r19 bytes4! int!;
|
|
r18 bytes4! int!;
|
|
r17 bytes4! int!;
|
|
r16 bytes4! int!;
|
|
r15 bytes4! int!;
|
|
r14 bytes4! int!;
|
|
|
|
f14 bytes4! float! volatile;
|
|
f13 bytes4! float! volatile;
|
|
f12 bytes4! float! volatile;
|
|
f11 bytes4! float! volatile;
|
|
f10 bytes4! float! volatile;
|
|
f9 bytes4! float! volatile;
|
|
f8 bytes4! float! volatile;
|
|
f7 bytes4! float! volatile;
|
|
f6 bytes4! float! volatile;
|
|
f5 bytes4! float! volatile;
|
|
f4 bytes4! float! volatile;
|
|
f3 bytes4! float! volatile;
|
|
f2 bytes4! float! volatile;
|
|
f1 bytes4! float! volatile;
|
|
f0 bytes4! float! volatile;
|
|
|
|
f31 bytes4! float!;
|
|
f30 bytes4! float!;
|
|
f29 bytes4! float!;
|
|
f28 bytes4! float!;
|
|
f27 bytes4! float!;
|
|
f26 bytes4! float!;
|
|
f25 bytes4! float!;
|
|
f24 bytes4! float!;
|
|
f23 bytes4! float!;
|
|
f22 bytes4! float!;
|
|
f21 bytes4! float!;
|
|
f20 bytes4! float!;
|
|
f19 bytes4! float!;
|
|
f18 bytes4! float!;
|
|
f17 bytes4! float!;
|
|
f16 bytes4! float!;
|
|
f15 bytes4! float!;
|
|
|
|
cr0 cr!;
|
|
|
|
|
|
DECLARATIONS
|
|
|
|
cr;
|
|
ubyte_to_be;
|
|
|
|
address fragment;
|
|
|
|
|
|
PATTERNS
|
|
|
|
/* Special */
|
|
|
|
PAIR(BLOCK4, BLOCK4);
|
|
|
|
|
|
|
|
/* Miscellaneous special things */
|
|
|
|
PUSH4(in:(int)reg)
|
|
emit "stwu %in, -4(sp)"
|
|
cost 4;
|
|
|
|
out:(int)reg = POP4
|
|
emit "lwz %out, 0(sp)"
|
|
emit "addi sp, sp, 4"
|
|
cost 8;
|
|
|
|
out:(float)reg = POPF4
|
|
emit "lfs %out, 0(sp)"
|
|
emit "addi sp, sp, 4"
|
|
cost 8;
|
|
|
|
RET
|
|
emit "ret"
|
|
cost 4;
|
|
|
|
SETRET4(in:(ret)reg)
|
|
emit "! setret4"
|
|
cost 4;
|
|
|
|
(ret)reg = GETRET4
|
|
emit "! getret4"
|
|
cost 1;
|
|
|
|
STACKADJUST4(delta:CONST4)
|
|
when signed_constant(%delta, 16)
|
|
emit "addi sp, sp, $delta"
|
|
cost 4;
|
|
|
|
|
|
|
|
/* Memory operations */
|
|
|
|
STORE4(addr:address, value:(int)reg)
|
|
emit "stw %value, %addr"
|
|
cost 4;
|
|
|
|
STORE2(addr:address, value:(int)reg)
|
|
emit "sth %value, %addr"
|
|
cost 4;
|
|
|
|
STORE1(addr:address, value:(int)ubyte_to_be)
|
|
emit "stb %value, %addr"
|
|
cost 4;
|
|
|
|
STORE1(ADD4(left:(int)reg, right:(int)reg), value:(int)ubyte_to_be)
|
|
emit "stbx %value, %left, %right"
|
|
cost 4;
|
|
|
|
out:(int)ubyte_to_be = in:(int)reg
|
|
emit "! reg -> ubyte"
|
|
cost 1;
|
|
|
|
out:(int)ubyte_to_be = CIU41(value:(int)reg)
|
|
emit "! CIU41(reg) -> ubyte"
|
|
cost 1;
|
|
|
|
out:(int)ubyte_to_be = CIU41(CII14(CIU41(value:(int)reg)))
|
|
emit "! CIU41(CII14(CIU41(reg))) -> ubyte"
|
|
cost 1;
|
|
|
|
out:(int)reg = LOAD4(addr:address)
|
|
emit "lwz %out, %addr"
|
|
cost 4;
|
|
|
|
out:(int)reg = LOAD2(addr:address)
|
|
emit "lhz %out, %addr"
|
|
cost 4;
|
|
|
|
out:(int)reg = LOAD1(addr:address)
|
|
emit "lbz %out, %addr"
|
|
cost 4;
|
|
|
|
out:(int)reg = CIU14(LOAD1(addr:address))
|
|
emit "lbz %out, %addr"
|
|
cost 4;
|
|
|
|
out:(int)reg = CIU24(LOAD2(addr:address))
|
|
emit "lhz %out, %addr"
|
|
cost 4;
|
|
|
|
|
|
|
|
/* Locals */
|
|
|
|
out:(int)reg = in:LOCAL4
|
|
emit "addi %out, fp, #$in"
|
|
cost 4;
|
|
|
|
address = in:LOCAL4
|
|
emit "$in(fp)";
|
|
|
|
|
|
|
|
/* Memory addressing modes */
|
|
|
|
address = ADD4(addr:(int)reg, offset:CONST4)
|
|
when signed_constant(%offset, 16)
|
|
emit "$offset(%addr)";
|
|
|
|
address = addr:(int)reg
|
|
emit "0(%addr)";
|
|
|
|
|
|
|
|
/* Branches */
|
|
|
|
JUMP(addr:BLOCK4)
|
|
emit "b $addr"
|
|
cost 4;
|
|
|
|
CJUMPEQ(value:(cr)cr, PAIR(true:BLOCK4, false:BLOCK4))
|
|
emit "bc IFTRUE, EQ, $true"
|
|
emit "b $false"
|
|
cost 8;
|
|
|
|
CJUMPLE(value:(cr)cr, PAIR(true:BLOCK4, false:BLOCK4))
|
|
emit "bc IFTRUE, LE, $true"
|
|
emit "b $false"
|
|
cost 8;
|
|
|
|
CJUMPLT(value:(cr)cr, PAIR(true:BLOCK4, false:BLOCK4))
|
|
emit "bc IFTRUE, LT, $true"
|
|
emit "b $false"
|
|
cost 8;
|
|
|
|
CALL(dest:LABEL4)
|
|
emit "bl $dest"
|
|
cost 4;
|
|
|
|
CALL(dest:(int)reg)
|
|
emit "mtspr ctr, %dest"
|
|
emit "bcctrl ALWAYS, 0, 0"
|
|
cost 8;
|
|
|
|
JUMP(dest:LABEL4)
|
|
emit "b $dest"
|
|
cost 4;
|
|
|
|
|
|
|
|
/* Comparisons */
|
|
|
|
cr:(cr)cr = COMPARES4(left:(int)reg, right:(int)reg)
|
|
emit "cmp %cr, 0, %left, %right"
|
|
cost 4;
|
|
|
|
cr:(cr)cr = COMPARES4(left:(int)reg, right:CONST4)
|
|
when signed_constant(%right, 16)
|
|
emit "cmpi %cr, 0, %left, $right"
|
|
cost 4;
|
|
|
|
cr:(cr)cr = COMPAREU4(left:(int)reg, right:(int)reg)
|
|
emit "cmpl %cr, 0, %left, %right"
|
|
cost 4;
|
|
|
|
cr:(cr)cr = COMPAREU4(left:(int)reg, right:CONST4)
|
|
when signed_constant(%right, 16)
|
|
emit "cmpli %cr, 0, %left, $right"
|
|
cost 4;
|
|
|
|
cr:(cr)cr = COMPARES4(COMPARES4(left:(int)reg, right:(int)reg), result:CONST4)
|
|
when specific_constant(%result, 0)
|
|
emit "cmp %cr, 0, %left, %right"
|
|
cost 4;
|
|
|
|
cr:(cr)cr = COMPARES4(COMPARES4(left:(int)reg, right:CONST4), result:CONST4)
|
|
when specific_constant(%result, 0)
|
|
when signed_constant(%right, 16)
|
|
emit "cmpi %cr, 0, %left, $right"
|
|
cost 4;
|
|
|
|
cr:(cr)cr = COMPARES4(COMPAREU4(left:(int)reg, right:(int)reg), result:CONST4)
|
|
when specific_constant(%result, 0)
|
|
emit "cmpl %cr, 0, %left, %right"
|
|
cost 4;
|
|
|
|
|
|
|
|
/* Conversions */
|
|
|
|
out:(int)reg = CII14(CIU41(value:(int)reg))
|
|
emit "extsb %out, %value"
|
|
cost 4;
|
|
|
|
out:(int)reg = CII24(CIU42(value:(int)reg))
|
|
emit "extsh %out, %value"
|
|
cost 4;
|
|
|
|
out:(int)reg = CIU41(in:(int)reg)
|
|
emit "andi %out, %in, 0xff"
|
|
cost 4;
|
|
|
|
out:(int)reg = CIU42(in:(int)reg)
|
|
emit "andi %out, %in, 0xffff"
|
|
cost 4;
|
|
|
|
out:(int)reg = CIU44(in:(int)reg)
|
|
emit "mr %out, %in ! ciu44"
|
|
cost 4;
|
|
|
|
out:(int)reg = CUI44(in:(int)reg)
|
|
emit "mr %out, %in ! cui44"
|
|
cost 4;
|
|
|
|
|
|
/* ALU operations */
|
|
|
|
out:(int)reg = ADD4(left:(int)reg, right:(int)reg)
|
|
emit "add %out, %left, %right"
|
|
cost 4;
|
|
|
|
out:(int)reg = ADD4(left:(int)reg, right:CONST4)
|
|
when signed_constant(%right, 16)
|
|
emit "addi %out, %left, $right"
|
|
cost 4;
|
|
|
|
out:(int)reg = SUB4(left:(int)reg, right:(int)reg)
|
|
emit "subf %out, %left, %right"
|
|
cost 4;
|
|
|
|
out:(int)reg = SUB4(left:(int)reg, right:CONST4)
|
|
emit "addi %out, %left, -($right)"
|
|
cost 4;
|
|
|
|
out:(int)reg = MUL4(left:(int)reg, right:(int)reg)
|
|
emit "mullw %out, %right, %left"
|
|
cost 4;
|
|
|
|
out:(int)reg = MOD4(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 = DIV4(left:(int)reg, right:(int)reg)
|
|
emit "divw %out, %left, %right"
|
|
cost 4;
|
|
|
|
out:(int)reg = ASL4(left:(int)reg, right:(int)reg)
|
|
emit "slw %out, %left, %right"
|
|
cost 4;
|
|
|
|
out:(int)reg = NEG4(left:(int)reg)
|
|
emit "neg %out, %left"
|
|
cost 4;
|
|
|
|
out:(int)reg = EOR4(left:(int)reg, right:(int)reg)
|
|
emit "xor %out, %right, %left"
|
|
cost 4;
|
|
|
|
out:(int)reg = value:LABEL4
|
|
emit "la %out, $value"
|
|
cost 4;
|
|
|
|
out:(int)reg = value:BLOCK4
|
|
emit "la %out, $value"
|
|
cost 4;
|
|
|
|
out:(int)reg = value:CONST4
|
|
emit "li %out, $value"
|
|
cost 8;
|
|
|
|
|
|
/* FPU operations */
|
|
|
|
out:(float)reg = value:CONSTF4
|
|
emit "lfs %out, address-containing-$value"
|
|
cost 8;
|
|
|
|
out:(float)reg = ADDF4(left:(float)reg, right:(float)reg)
|
|
emit "fadds %out, %left, %right"
|
|
cost 4;
|
|
|
|
out:(float)reg = SUBF4(left:(float)reg, right:(float)reg)
|
|
emit "fsubs %out, %left, %right"
|
|
cost 4;
|
|
|
|
|
|
/* vim: set sw=4 ts=4 expandtab : */
|
|
|