Made csa and csb work with mcg; adjust the libem functions and the
corresponding invocation in the ncg table so the same helpers can be used for both mcg and ncg. Add a new IR opcode, FARJUMP, which jumps to a helper function but saves volatile registers.
This commit is contained in:
		
							parent
							
								
									5208e5f751
								
							
						
					
					
						commit
						d31bc6a3f9
					
				
					 10 changed files with 75 additions and 13 deletions
				
			
		| 
						 | 
				
			
			@ -12,11 +12,14 @@
 | 
			
		|||
! address and jumps to it.
 | 
			
		||||
! traps if resulting address is zero
 | 
			
		||||
!
 | 
			
		||||
! On entry: r3 = address of CSA table
 | 
			
		||||
!           r4 = value
 | 
			
		||||
! Stack: ( value tableaddr -- )
 | 
			
		||||
 | 
			
		||||
.define .csa
 | 
			
		||||
.csa:
 | 
			
		||||
	lwz r3, 0(sp)
 | 
			
		||||
	lwz r4, 4(sp)
 | 
			
		||||
	addi sp, sp, 8
 | 
			
		||||
 | 
			
		||||
	lwz r5, 0(r3)            ! load default
 | 
			
		||||
	mtspr ctr, r5
 | 
			
		||||
	
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,11 +12,14 @@
 | 
			
		|||
! address and jumps to it.
 | 
			
		||||
! traps if resulting address is zero
 | 
			
		||||
!
 | 
			
		||||
! On entry: r3 = address of CSB table
 | 
			
		||||
!           r4 = value
 | 
			
		||||
! Stack: ( value tableaddr -- )
 | 
			
		||||
 | 
			
		||||
.define .csb
 | 
			
		||||
.csb:
 | 
			
		||||
	lwz r3, 0(sp)
 | 
			
		||||
	lwz r4, 4(sp)
 | 
			
		||||
	addi sp, sp, 8
 | 
			
		||||
 | 
			
		||||
	lwz r5, 0(r3)            ! load default
 | 
			
		||||
	mtspr ctr, r5
 | 
			
		||||
	
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -466,6 +466,11 @@ PATTERNS
 | 
			
		|||
		emit "b $addr"
 | 
			
		||||
		cost 4;
 | 
			
		||||
 | 
			
		||||
	FARJUMP(addr:LABEL.I)
 | 
			
		||||
        with corrupted(volatile)
 | 
			
		||||
		emit "b $addr"
 | 
			
		||||
		cost 4;
 | 
			
		||||
 | 
			
		||||
    JUMP(dest:(int)reg)
 | 
			
		||||
        emit "mtspr ctr, %dest"
 | 
			
		||||
        emit "bcctrl 20, 0, 0"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1898,12 +1898,12 @@ PATTERNS
 | 
			
		|||
				addi SP, SP, {CONST, 12}
 | 
			
		||||
				
 | 
			
		||||
	pat csa                            /* Array-lookup switch */
 | 
			
		||||
		with GPR3 GPR4 STACK
 | 
			
		||||
		with STACK
 | 
			
		||||
			gen
 | 
			
		||||
				b {LABEL, ".csa"}
 | 
			
		||||
				
 | 
			
		||||
	pat csb                            /* Table-lookup switch */
 | 
			
		||||
		with GPR3 GPR4 STACK
 | 
			
		||||
		with STACK
 | 
			
		||||
			gen
 | 
			
		||||
				b {LABEL, ".csb"}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1130,9 +1130,8 @@ static void insn_ivalue(int opcode, arith value)
 | 
			
		|||
        case op_csa:
 | 
			
		||||
        case op_csb:
 | 
			
		||||
        {
 | 
			
		||||
            const char* helper = aprintf(".%s%d",
 | 
			
		||||
                (opcode == op_csa) ? "csa" : "csb",
 | 
			
		||||
                value);
 | 
			
		||||
            const char* helper = aprintf(".%s",
 | 
			
		||||
                (opcode == op_csa) ? "csa" : "csb");
 | 
			
		||||
            struct ir* descriptor = pop(EM_pointersize);
 | 
			
		||||
 | 
			
		||||
            if (descriptor->opcode != IR_LABEL)
 | 
			
		||||
| 
						 | 
				
			
			@ -1143,7 +1142,7 @@ static void insn_ivalue(int opcode, arith value)
 | 
			
		|||
            materialise_stack();
 | 
			
		||||
            appendir(
 | 
			
		||||
                new_ir2(
 | 
			
		||||
                    IR_JUMP, 0,
 | 
			
		||||
                    IR_FARJUMP, 0,
 | 
			
		||||
                    new_labelir(helper),
 | 
			
		||||
                    extract_block_refs(bb_get(descriptor->u.lvalue))
 | 
			
		||||
                )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,8 +33,7 @@ var C_INCLUDES=-I{PLATFORMDIR}/include -I{EM}/share/ack/include/ansi
 | 
			
		|||
name be
 | 
			
		||||
	from .m.g
 | 
			
		||||
	to .s
 | 
			
		||||
	# Change this back to ncg to revert to the old code generator
 | 
			
		||||
	program {EM}/lib/ack/{PLATFORM}/ncg
 | 
			
		||||
	program {EM}/lib/ack/{PLATFORM}/mcg
 | 
			
		||||
	mapflag -gdb GF=-gdb
 | 
			
		||||
	args {GF?} <
 | 
			
		||||
	stdout
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										26
									
								
								plat/qemuppc/tests/csa_e.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								plat/qemuppc/tests/csa_e.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,26 @@
 | 
			
		|||
#include "test.h"
 | 
			
		||||
 | 
			
		||||
int csa(int i)
 | 
			
		||||
{
 | 
			
		||||
    switch (i)
 | 
			
		||||
    {
 | 
			
		||||
        case 2:  return 2;
 | 
			
		||||
        case 3:  return 3;
 | 
			
		||||
        case 4:  return 4;
 | 
			
		||||
        default: return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Bypasses the CRT, so there's no stdio or BSS initialisation. */
 | 
			
		||||
void _m_a_i_n(void)
 | 
			
		||||
{
 | 
			
		||||
    ASSERT(csa(0) == 0);
 | 
			
		||||
    ASSERT(csa(1) == 0);
 | 
			
		||||
    ASSERT(csa(2) == 2);
 | 
			
		||||
    ASSERT(csa(3) == 3);
 | 
			
		||||
    ASSERT(csa(4) == 4);
 | 
			
		||||
    ASSERT(csa(5) == 0);
 | 
			
		||||
    ASSERT(csa(6) == 0);
 | 
			
		||||
 | 
			
		||||
    finished();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										26
									
								
								plat/qemuppc/tests/csb_e.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								plat/qemuppc/tests/csb_e.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,26 @@
 | 
			
		|||
#include "test.h"
 | 
			
		||||
 | 
			
		||||
int csa(int i)
 | 
			
		||||
{
 | 
			
		||||
    switch (i)
 | 
			
		||||
    {
 | 
			
		||||
        case 200:  return 200;
 | 
			
		||||
        case 300:  return 300;
 | 
			
		||||
        case 400:  return 400;
 | 
			
		||||
        default: return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Bypasses the CRT, so there's no stdio or BSS initialisation. */
 | 
			
		||||
void _m_a_i_n(void)
 | 
			
		||||
{
 | 
			
		||||
    ASSERT(csa(0) == 0);
 | 
			
		||||
    ASSERT(csa(100) == 0);
 | 
			
		||||
    ASSERT(csa(200) == 200);
 | 
			
		||||
    ASSERT(csa(300) == 300);
 | 
			
		||||
    ASSERT(csa(400) == 400);
 | 
			
		||||
    ASSERT(csa(500) == 0);
 | 
			
		||||
    ASSERT(csa(600) == 0);
 | 
			
		||||
 | 
			
		||||
    finished();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -103,6 +103,7 @@ S ?=i. SETRET
 | 
			
		|||
 | 
			
		||||
# Flow control --- these never return
 | 
			
		||||
V .=i. JUMP
 | 
			
		||||
V .=i. FARJUMP
 | 
			
		||||
V .=i. CJUMPEQ
 | 
			
		||||
V .=i. CJUMPLT
 | 
			
		||||
V .=i. CJUMPLE
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue