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
|
||||
.define .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
|
||||
|
||||
.define .trp
|
||||
|
|
Loading…
Reference in a new issue