inasmuch as it looks better before register allocation. Basic blocks now know their own successors and predecessors (after a certain point in the IR processing).
		
			
				
	
	
		
			245 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			245 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| REGISTERS
 | |
| 
 | |
| 	r0  any int ret;
 | |
| 	r1  any int;
 | |
| 	r2  any int;
 | |
| 	r3  any int;
 | |
| 	r4  any int;
 | |
| 	r5  any int;
 | |
| 	r6  any int;
 | |
| 	r7  any int;
 | |
| 	r8  any int;
 | |
| 	r9  any int;
 | |
| 	r10 any int;
 | |
| 	r11 any int;
 | |
| 
 | |
| 	s0  any float;
 | |
| 	s1  any float;
 | |
| 	s2  any float;
 | |
| 	s3  any float;
 | |
| 	s4  any float;
 | |
| 	s5  any float;
 | |
| 	s6  any float;
 | |
| 	s7  any float;
 | |
| 	s8  any float;
 | |
| 	s9  any float;
 | |
| 
 | |
| 	cc  cc;
 | |
| 
 | |
| 
 | |
| DECLARATIONS
 | |
| 
 | |
| 	address   fragment;
 | |
| 	aluparam  fragment;
 | |
| 
 | |
| 
 | |
| PATTERNS
 | |
| 
 | |
| /* Special */
 | |
| 
 | |
| 	int;
 | |
| 	float;
 | |
| 	any;
 | |
| 
 | |
| 	PAIR(BLOCK4, BLOCK4);
 | |
| 
 | |
| 
 | |
| /* Miscellaneous special things */
 | |
| 
 | |
| 	PUSH4(in:int)
 | |
| 		emit "push %in"
 | |
| 		cost 4;
 | |
| 
 | |
| 	int = POP4
 | |
| 		emit "pop %int"
 | |
| 		cost 4;
 | |
| 
 | |
| 	RET
 | |
| 		emit "ret"
 | |
| 		cost 4;
 | |
| 
 | |
| 	SETRET4(in:ret)
 | |
| 		emit "mov r0, %in"
 | |
| 		cost 4;
 | |
| 
 | |
| 	STACKADJUST4(delta:aluparam)
 | |
| 		emit "add sp, sp, %delta"
 | |
| 		cost 4;
 | |
| 
 | |
| 	int = in:REG4
 | |
| 		prefers int(in)
 | |
| 		cost 1;
 | |
| 
 | |
| 	int = NOP4(in:int)
 | |
| 		emit "mov %int, %in"
 | |
| 		cost 1;
 | |
| 
 | |
| 	any = PHI4
 | |
| 		cost 0;
 | |
| 
 | |
| 	float = in:REG4
 | |
| 		prefers float(in)
 | |
| 		cost 1;
 | |
| 
 | |
| 	ret = in:any emit "mov %ret, %in" cost 1;
 | |
| 	any = in:int emit "mov %any, %in" cost 1;
 | |
| 	int = in:any emit "mov %int, %in" cost 1;
 | |
| 	any = in:float emit "mov %any, %in" cost 1;
 | |
| 	float = in:any emit "mov %float, %in" cost 1;
 | |
| 
 | |
| 
 | |
| /* Memory operations */
 | |
| 
 | |
| 	STORE4(addr:address, value:int)
 | |
| 		emit "str %value, %addr"
 | |
| 		cost 4;
 | |
| 
 | |
| 	STORE1(addr:address, value:int)
 | |
| 		emit "strb %value, %addr"
 | |
| 		cost 4;
 | |
| 
 | |
| 	int = LOAD4(addr:address)
 | |
| 		emit "ldr %int, %addr"
 | |
| 		cost 4;
 | |
| 
 | |
| 	int = LOAD1(addr:address)
 | |
| 		emit "ldrb %int, %addr"
 | |
| 		cost 4;
 | |
| 
 | |
| 	int = CIU14(LOAD1(addr:address))
 | |
| 		emit "ldrb %int, %addr"
 | |
| 		cost 4;
 | |
| 	
 | |
| 	int = CII14(CIU41(CIU14(LOAD1(addr:address))))
 | |
| 		emit "ldrsb %int, %addr"
 | |
| 		cost 4;
 | |
| 
 | |
| 
 | |
| /* Locals */
 | |
| 
 | |
| 	int = in:LOCAL4
 | |
| 		emit "add %int, fp, #$in"
 | |
| 		cost 4;
 | |
| 
 | |
| 	address = in:LOCAL4
 | |
| 		emit "[fp, #$in]";
 | |
| 
 | |
| 
 | |
| /* Memory addressing modes */
 | |
| 
 | |
| 	address = ADD4(addr:int, offset:CONST4)
 | |
| 		emit "[%addr, #$offset]";
 | |
| 
 | |
| 	address = ADD4(addr1:int, addr2:int)
 | |
| 		emit "[%addr1, %addr2]";
 | |
| 
 | |
| 	address = addr:int
 | |
| 		emit "[%addr]";
 | |
| 
 | |
| 
 | |
| 
 | |
| /* Branches */
 | |
| 
 | |
| 	JUMP(addr:BLOCK4)
 | |
| 		emit "b $addr"
 | |
| 		cost 4;
 | |
| 
 | |
| 	CJUMPEQ(value:cc, PAIR(true:BLOCK4, false:BLOCK4))
 | |
| 		emit "beq $true"
 | |
| 		emit "b $false"
 | |
| 		cost 8;
 | |
| 
 | |
| 	CJUMPLE(value:cc, PAIR(true:BLOCK4, false:BLOCK4))
 | |
| 		emit "ble $true"
 | |
| 		emit "b $false"
 | |
| 		cost 8;
 | |
| 
 | |
| 	CJUMPLT(value:cc, PAIR(true:BLOCK4, false:BLOCK4))
 | |
| 		emit "blt $true"
 | |
| 		emit "b $false"
 | |
| 		cost 8;
 | |
| 
 | |
| 	CALL(dest:LABEL4)
 | |
| 		emit "bl $dest"
 | |
| 		cost 4;
 | |
| 
 | |
| 
 | |
| /* Comparisons */
 | |
| 
 | |
| 	cc = COMPARES4(left:int, right:aluparam)
 | |
| 		emit "cmp %left, %right"
 | |
| 		cost 4;
 | |
| 
 | |
| 	cc = COMPARES4(COMPARES4(left:int, right:aluparam), CONST4)
 | |
| 		emit "cmp %left, %right"
 | |
| 		cost 4;
 | |
| 
 | |
| 	int = cc
 | |
| 		emit "mov %int, #0"
 | |
| 		emit "movlt %int, #-1"
 | |
| 		emit "movgt %int, #1"
 | |
| 		cost 12;
 | |
| 
 | |
| 
 | |
| /* Conversions */
 | |
| 
 | |
| 	int = CII14(CIU41(value:int))
 | |
| 		emit "sxtb %int, %value"
 | |
| 		cost 4;
 | |
| 
 | |
| 	int = CIU41(in:int)
 | |
| 		emit "and %int, %in, #0xff"
 | |
| 		cost 4;
 | |
| 
 | |
| 
 | |
| /* ALU operations */
 | |
| 
 | |
| 	int = ADD4(left:int, right:aluparam)
 | |
| 		emit "add %int, %left, %right"
 | |
| 		cost 4;
 | |
| 
 | |
| 	int = ADD4(left:aluparam, right:int)
 | |
| 		emit "add %int, %right, %left"
 | |
| 		cost 4;
 | |
| 
 | |
| 	int = MOD4(left:int, right:int)
 | |
| 		emit "udiv %int, %left, %right"
 | |
| 		emit "mls %int, %int, %right, %left"
 | |
| 		cost 8;
 | |
| 
 | |
| 	int = DIV4(left:int, right:aluparam)
 | |
| 		emit "div %int, %left, %right"
 | |
| 		cost 4;
 | |
| 
 | |
| 	aluparam = value:CONST4
 | |
| 		emit "#$value";
 | |
| 
 | |
| 	aluparam = value:int
 | |
| 		emit "%value";
 | |
| 
 | |
| 	int = value:aluparam
 | |
| 		emit "mov %int, %value"
 | |
| 		cost 4;
 | |
| 
 | |
| 	int = value:LABEL4
 | |
| 		emit "adr %int, $value"
 | |
| 		cost 4;
 | |
| 
 | |
| 	int = value:BLOCK4
 | |
| 		emit "adr %int, $value"
 | |
| 		cost 4;
 | |
| 
 | |
| 	int = value:CONST4
 | |
| 		emit "ldr %int, address-containing-$value"
 | |
| 		cost 8;
 | |
| 
 | |
| 	float = value:CONSTF4
 | |
| 		emit "vldr %float, address-containing-$value"
 | |
| 		cost 8;
 | |
| 
 | |
| /* FPU operations */
 | |
| 
 | |
| 	float = ADDF4(left:float, right:float)
 | |
| 		emit "fadds %float, %left, %right"
 | |
| 		cost 4;
 | |
| 
 |