406 lines
		
	
	
	
		
			8.4 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			406 lines
		
	
	
	
		
			8.4 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| 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;
 | |
|     ushort;
 | |
| 
 | |
| 	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 */
 | |
| 
 | |
|     /* Stores */
 | |
| 
 | |
| 	STORE4(addr:address, value:(int)reg)
 | |
| 		emit "stw %value, %addr"
 | |
| 		cost 4;
 | |
| 
 | |
| 	STORE2(addr:address, value:(int)ushort)
 | |
| 		emit "sth %value, %addr"
 | |
| 		cost 4;
 | |
| 
 | |
|     STORE2(ADD4(left:(int)reg, right:(int)reg), value:(int)ushort)
 | |
|         emit "sthx %value, %left, %right"
 | |
|         cost 4;
 | |
| 
 | |
|     STORE1(addr:address, value:(int)ubyte)
 | |
| 		emit "stb %value, %addr"
 | |
| 		cost 4;
 | |
| 
 | |
|     STORE1(ADD4(left:(int)reg, right:(int)reg), value:(int)ubyte)
 | |
|         emit "stbx %value, %left, %right"
 | |
|         cost 4;
 | |
| 
 | |
|     /* Loads */
 | |
| 
 | |
| 	out:(int)reg = LOAD4(addr:address)
 | |
| 		emit "lwz %out, %addr"
 | |
| 		cost 4;
 | |
| 
 | |
| 	out:(int)ushort = LOAD2(addr:address)
 | |
| 		emit "lhz %out, %addr"
 | |
| 		cost 4;
 | |
| 
 | |
| 	out:(int)ubyte = LOAD1(addr:address)
 | |
| 		emit "lbz %out, %addr"
 | |
| 		cost 4;
 | |
| 
 | |
|     /* Conversions to ubyte and ushort */
 | |
| 
 | |
|     out:(int)ubyte = in:(int)reg
 | |
|         with %out == %in
 | |
|         emit "! reg -> ubyte"
 | |
|         cost 1;
 | |
| 
 | |
|     out:(int)ubyte = CIU41(value:(int)reg)
 | |
|         with %out == %value
 | |
|         emit "! CIU41(reg) -> ubyte"
 | |
|         cost 1;
 | |
| 
 | |
|     out:(int)ubyte = CIU41(CII14(CIU41(value:(int)reg)))
 | |
|         with %out == %value
 | |
|         emit "! CIU41(CII14(CIU41(reg))) -> ubyte"
 | |
|         cost 1;
 | |
| 
 | |
|     out:(int)ushort = in:(int)reg
 | |
|         with %out == %in
 | |
|         emit "! reg -> ushort"
 | |
|         cost 1;
 | |
| 
 | |
|     out:(int)ushort = CIU42(value:(int)reg)
 | |
|         with %out == %value
 | |
|         emit "! CIU42(reg) -> ushort"
 | |
|         cost 1;
 | |
| 
 | |
|     out:(int)ushort = CIU42(CII24(CIU42(value:(int)reg)))
 | |
|         with %out == %value
 | |
|         emit "! CIU42(CII24(CIU42(reg))) -> ushort"
 | |
|         cost 1;
 | |
| 
 | |
|     /* Conversions from ubyte and ushort */
 | |
| 
 | |
|     out:(int)reg = CIU14(in:(int)ubyte)
 | |
|         with %out == %in
 | |
|         emit "! CIU14"
 | |
|         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 : */
 | |
| 
 |