diff --git a/mach/mips/libem/csa.s b/mach/mips/libem/csa.s new file mode 100644 index 000000000..b03572511 --- /dev/null +++ b/mach/mips/libem/csa.s @@ -0,0 +1,41 @@ +# +.sect .text; .sect .rom; .sect .data; .sect .bss + +/* This is not a subroutine, but just a + * piece of code that computes the jump- + * address and jumps to it. + * traps if resulting address is zero + * + * Stack: ( value tableaddr -- ) + */ + +.define .csa +.csa: + lw r4, 0(sp) /* r4 = table */ + lw r5, 0(sp) /* r5 = value */ + addiu sp, sp, 8 + + lw r6, 0(r4) /* r6 = default target */ + lw r7, 4(r4) /* r7 = lower bound */ + subu r5, r5, r6 /* adjust value */ + bltz r5, 1f /* jump to default if out of range */ + nop + + lw r7, 8(r4) /* fetch range */ + subu r7, r5, r7 /* compute (adjusted value - range) */ + blez r7, 1f /* jump to default if out of range */ + nop + + addiu r4, r4, 12 /* skip header */ + sll r5, r5, 2 /* value = value<<2 */ + addu r4, r4, r5 /* find address of target */ + lw r6, 0(r4) /* r6 = new target */ + +1: + beq r6, zero, 2f /* trap if null */ + nop + jr r6 /* otherwise jump */ + nop +2: + j .trap_ecase + nop diff --git a/mach/mips/libem/csb.s b/mach/mips/libem/csb.s new file mode 100644 index 000000000..acc1f636e --- /dev/null +++ b/mach/mips/libem/csb.s @@ -0,0 +1,47 @@ +# +.sect .text; .sect .rom; .sect .data; .sect .bss + +/* this is not a subroutine, but just a + * piece of code that computes the jump- + * address and jumps to it. + * traps if resulting address is zero + * + * Stack: ( value tableaddr -- ) + */ + +.sect .text +.define .csb +.csb: + lw r4, 0(sp) ! r4 = address of table + lw r5, 0(sp) ! r5 = value + addiu sp, sp, 8 + + lw r6, 0(r4) ! r6 = default target + lw r7, 4(r4) ! r7 = table count + +2: + addiu r7, r7, -1 ! decrement count + bltz r7, 1f ! exit loop if out + nop + + lw r8, 8(r4) ! candidate value + beq r8, r5, 3f ! branch if equal + nop + + addiu r4, r4, 8 ! next entry + b 2b + nop + +3: + /* We found an item in the table. */ + lw r6, 12(r4) ! load jump target + /* fall through */ +1: + beq r6, zero, 4f /* trap if null */ + nop + jr r6 /* otherwise jump */ + nop +4: + j .trap_ecase + nop + diff --git a/mach/mips/libem/trp.s b/mach/mips/libem/trp.s index 58187079e..827a50b85 100644 --- a/mach/mips/libem/trp.s +++ b/mach/mips/libem/trp.s @@ -8,6 +8,7 @@ li r3, 20 ! ECASE = 20 in h/em_abs.h ! FALLTHROUGH to .trp +.define .trp .trp: syscall 0