Lots more untested helper functions.
This commit is contained in:
parent
f8f6fa9fc1
commit
185e910246
39
mach/mips/libem/aar4.s
Normal file
39
mach/mips/libem/aar4.s
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#
|
||||||
|
.sect .text; .sect .rom; .sect .data; .sect .bss
|
||||||
|
|
||||||
|
/* Get address of element of bounds-checked array.
|
||||||
|
*
|
||||||
|
* Stack: ( array-adr index descriptor-adr -- element-adr )
|
||||||
|
* Sets r2 = size of element for .los4, .sts4
|
||||||
|
* Preserves r25 (the last volatile register)
|
||||||
|
*/
|
||||||
|
|
||||||
|
.sect .text
|
||||||
|
.define .aar4
|
||||||
|
.aar4:
|
||||||
|
lw r4, 0(sp) ! r4 = address of descriptor
|
||||||
|
lw r5, 0(sp) ! r5 = index
|
||||||
|
lw r6, 0(sp) ! r6 = address of array
|
||||||
|
|
||||||
|
lw r7, 0(r4) ! at = lower bound
|
||||||
|
slt at, r7, at ! at = r5 < at
|
||||||
|
bne at, zero, .trap_earray
|
||||||
|
|
||||||
|
lw at, 4(r4) ! at = upper bound
|
||||||
|
slt at, at, r5 ! at = at < r5
|
||||||
|
bne at, zero, .trap_earray
|
||||||
|
|
||||||
|
lw r2, 8(r4) ! r2 = size of element
|
||||||
|
subu r5, r5, r7 ! adjust index for non-zero lower bound
|
||||||
|
mul r5, r5, r2 ! scale index by size
|
||||||
|
addu r5, r5, r6 ! calculate address of element
|
||||||
|
|
||||||
|
sw r5, 8(sp) ! push address of element
|
||||||
|
addiu sp, sp, 8
|
||||||
|
jr ra
|
||||||
|
nop
|
||||||
|
|
||||||
|
.define .trap_earray
|
||||||
|
.trap_earray:
|
||||||
|
li r4, 0 ! EARRAY = 0 in h/em_abs.h
|
||||||
|
b .trp
|
28
mach/mips/libem/dus4.s
Normal file
28
mach/mips/libem/dus4.s
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#
|
||||||
|
.sect .text; .sect .rom; .sect .data; .sect .bss
|
||||||
|
|
||||||
|
/* Duplicates some words on top of stack.
|
||||||
|
* Stack: ( a size -- a a )
|
||||||
|
*/
|
||||||
|
|
||||||
|
.sect .text
|
||||||
|
.define .dus4
|
||||||
|
.dus4:
|
||||||
|
lw r4, 0(sp) ! r4 = size
|
||||||
|
addiu sp, sp, 4 ! sp = pointer to a
|
||||||
|
mov r5, sp ! r5 = pointer to a
|
||||||
|
subu sp, sp, r4 ! sp = pointer to newa
|
||||||
|
mov r6, sp ! r6 = pointer to b
|
||||||
|
|
||||||
|
srl r4, r4, 2 ! r4 = number of words
|
||||||
|
1:
|
||||||
|
lw at, 0(r5)
|
||||||
|
sw at, 0(r6)
|
||||||
|
addiu r5, r5, 4
|
||||||
|
addiu r6, r6, 4
|
||||||
|
addiu r4, r4, -1
|
||||||
|
bne r4, zero, 1b
|
||||||
|
nop
|
||||||
|
|
||||||
|
jr ra
|
||||||
|
nop
|
31
mach/mips/libem/exg.s
Normal file
31
mach/mips/libem/exg.s
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#
|
||||||
|
.sect .text; .sect .rom; .sect .data; .sect .bss
|
||||||
|
|
||||||
|
/* Exchange top two values on stack.
|
||||||
|
* Stack: ( a b size -- b a )
|
||||||
|
*/
|
||||||
|
|
||||||
|
.sect .text
|
||||||
|
.define .exg
|
||||||
|
.exg:
|
||||||
|
lw r4, 0(sp) ! r4 = size
|
||||||
|
srl r5, r4, 2 ! r5 = number of words
|
||||||
|
addiu sp, sp, 4 ! adjust stack for input/output parameter size
|
||||||
|
|
||||||
|
mov r6, sp ! r6 = pointer to b
|
||||||
|
addu r7, r6, r4 ! r7 = pointer to a
|
||||||
|
|
||||||
|
! Loop to swap each pair of words.
|
||||||
|
1:
|
||||||
|
lw r8, 0(r6)
|
||||||
|
lw r9, 0(r7)
|
||||||
|
sw r9, 0(r6)
|
||||||
|
sw r8, 0(r7)
|
||||||
|
addiu r6, r6, 4
|
||||||
|
addiu r7, r7, 4
|
||||||
|
addiu r5, r5, -1
|
||||||
|
bne r5, zero, 1b
|
||||||
|
nop
|
||||||
|
|
||||||
|
jr ra
|
||||||
|
nop
|
33
mach/mips/libem/inn.s
Normal file
33
mach/mips/libem/inn.s
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#
|
||||||
|
.sect .text; .sect .rom; .sect .data; .sect .bss
|
||||||
|
|
||||||
|
/* Tests a bit in a bitset on the stack.
|
||||||
|
*
|
||||||
|
* Stack: ( bitset bitnum setsize -- bool )
|
||||||
|
*
|
||||||
|
* Some back ends push false if bitnum is too large. We don't because
|
||||||
|
* the compilers tend to pass a small enough bitnum.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.sect .text
|
||||||
|
.define .inn
|
||||||
|
.inn:
|
||||||
|
lw r4, 0(sp) ! r4 = size of set (bytes)
|
||||||
|
lw r5, 0(sp) ! r5 = bit number
|
||||||
|
addiu sp, sp, 8 ! sp now points at bitset
|
||||||
|
|
||||||
|
srl r6, r5, 3 ! r6 = offset of word in set
|
||||||
|
addu r6, sp, r6 ! r6 = address of word in set
|
||||||
|
lw r6, 0(r6) ! r6 = word
|
||||||
|
|
||||||
|
ext r7, r5, 0, 3 ! r7 = bit number within word
|
||||||
|
srlv r6, r6, r7 ! r7 = candidate bit now at bit 0
|
||||||
|
andi r6, r6, 1 ! r7 = bool
|
||||||
|
|
||||||
|
addu sp, sp, r4 ! retract over bitfield
|
||||||
|
|
||||||
|
addiu sp, sp, -4
|
||||||
|
sw r6, 0(sp) ! push result
|
||||||
|
|
||||||
|
jr ra
|
||||||
|
nop
|
23
mach/mips/libem/lar4.s
Normal file
23
mach/mips/libem/lar4.s
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#
|
||||||
|
.sect .text; .sect .rom; .sect .data; .sect .bss
|
||||||
|
|
||||||
|
/* Load from bounds-checked array.
|
||||||
|
*
|
||||||
|
* Stack: ( array-adr index descriptor-adr -- element )
|
||||||
|
*/
|
||||||
|
|
||||||
|
.sect .text
|
||||||
|
.define .lar4
|
||||||
|
.lar4:
|
||||||
|
mov r25, ra
|
||||||
|
|
||||||
|
jal .aar4
|
||||||
|
nop
|
||||||
|
|
||||||
|
/* pass r2 = size from .aar4 to .los4
|
||||||
|
|
||||||
|
jal .los4
|
||||||
|
nop
|
||||||
|
|
||||||
|
jr r25
|
||||||
|
nop
|
55
mach/mips/libem/los4.s
Normal file
55
mach/mips/libem/los4.s
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
#
|
||||||
|
.sect .text; .sect .rom; .sect .data; .sect .bss
|
||||||
|
|
||||||
|
/* Loads a variable-sized block onto the stack.
|
||||||
|
*
|
||||||
|
* On entry: r2 = size
|
||||||
|
* Stack: ( address -- block )
|
||||||
|
* Preserves r25 for .lar4 and .sar4
|
||||||
|
*/
|
||||||
|
|
||||||
|
.sect .text
|
||||||
|
.define .los4
|
||||||
|
.los4:
|
||||||
|
lw r4, 0(sp) ! r4 = address
|
||||||
|
|
||||||
|
! Sizes 1 and 2 are handled specially.
|
||||||
|
|
||||||
|
li at, 1
|
||||||
|
beq r2, at, byte_sized
|
||||||
|
nop
|
||||||
|
|
||||||
|
li at, 2
|
||||||
|
beq r2, at, word_sized
|
||||||
|
nop
|
||||||
|
|
||||||
|
! Else the size must be a multiple of 4.
|
||||||
|
|
||||||
|
srl r5, r2, 2 ! r5 = number of words
|
||||||
|
addiu sp, sp, 4 ! adjust to end of block
|
||||||
|
subu sp, sp, r4 ! sp = start of block
|
||||||
|
mov r6, sp ! r6 = start of block
|
||||||
|
|
||||||
|
1:
|
||||||
|
lw at, 0(r2)
|
||||||
|
sw at, 0(r6)
|
||||||
|
addiu r2, r2, 4
|
||||||
|
addiu r6, r6, 4
|
||||||
|
addiu r5, r5, -1
|
||||||
|
bne r5, zero, 1b
|
||||||
|
nop
|
||||||
|
|
||||||
|
jr ra
|
||||||
|
nop
|
||||||
|
|
||||||
|
byte_sized:
|
||||||
|
lb at, 0(r4)
|
||||||
|
sw at, 0(sp)
|
||||||
|
jr ra
|
||||||
|
nop
|
||||||
|
|
||||||
|
word_sized:
|
||||||
|
lh at, 0(r4)
|
||||||
|
sw at, 0(sp)
|
||||||
|
jr ra
|
||||||
|
nop
|
33
mach/mips/libem/rck.s
Normal file
33
mach/mips/libem/rck.s
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#
|
||||||
|
.sect .text; .sect .rom; .sect .data; .sect .bss
|
||||||
|
|
||||||
|
/* Bounds check. Traps if the value is out of range.
|
||||||
|
* Stack: ( value descriptor -- value )
|
||||||
|
*
|
||||||
|
* This ".rck" only works with 4-byte integers. The name is ".rck" and
|
||||||
|
* not ".rck4" because many back ends only do rck with the word size.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.sect .text
|
||||||
|
.define .rck
|
||||||
|
.rck:
|
||||||
|
lw r4, 0(sp) ! r4 = pointer to descriptor
|
||||||
|
addiu sp, sp, 4 ! leave value on stack
|
||||||
|
lw r5, 0(sp) ! r5 = value
|
||||||
|
|
||||||
|
lw at, 0(sp) ! at = lower bound
|
||||||
|
slt at, r5, at ! at = r5 < at
|
||||||
|
bne at, zero, .trap_erange
|
||||||
|
|
||||||
|
lw at, 4(sp) ! at = upper bound
|
||||||
|
slt at, at, r5 ! at = at < r5
|
||||||
|
bne at, zero, .trap_erange
|
||||||
|
|
||||||
|
jr ra
|
||||||
|
nop
|
||||||
|
|
||||||
|
.define .trap_erange
|
||||||
|
.trap_erange:
|
||||||
|
li r4, 1
|
||||||
|
j .trp
|
||||||
|
nop
|
|
@ -7,7 +7,7 @@
|
||||||
.sect .text
|
.sect .text
|
||||||
.define .trap_ecase
|
.define .trap_ecase
|
||||||
.trap_ecase:
|
.trap_ecase:
|
||||||
li r3, 20 ! ECASE = 20 in h/em_abs.h
|
li r4, 20 ! ECASE = 20 in h/em_abs.h
|
||||||
! FALLTHROUGH to .trp
|
! FALLTHROUGH to .trp
|
||||||
|
|
||||||
.define .trp
|
.define .trp
|
||||||
|
|
Loading…
Reference in a new issue