2018-09-08 21:12:57 +00:00
|
|
|
#
|
|
|
|
.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 -- )
|
|
|
|
*/
|
|
|
|
|
2018-09-09 10:24:22 +00:00
|
|
|
.sect .text
|
2018-09-08 21:12:57 +00:00
|
|
|
.define .csa
|
|
|
|
.csa:
|
|
|
|
lw r4, 0(sp) /* r4 = table */
|
2018-09-13 22:15:43 +00:00
|
|
|
lw r5, 4(sp) /* r5 = value */
|
2018-09-08 21:12:57 +00:00
|
|
|
addiu sp, sp, 8
|
|
|
|
|
|
|
|
lw r6, 0(r4) /* r6 = default target */
|
|
|
|
lw r7, 4(r4) /* r7 = lower bound */
|
2018-09-13 22:15:43 +00:00
|
|
|
subu r5, r5, r7 /* adjust value */
|
2018-09-08 21:12:57 +00:00
|
|
|
bltz r5, 1f /* jump to default if out of range */
|
|
|
|
nop
|
|
|
|
|
|
|
|
lw r7, 8(r4) /* fetch range */
|
2018-09-13 22:15:43 +00:00
|
|
|
subu r7, r7, r5 /* compute difference within range */
|
|
|
|
bltz r7, 1f /* jump to default if out of range */
|
2018-09-08 21:12:57 +00:00
|
|
|
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
|