Lots more untested helper functions.

This commit is contained in:
David Given 2018-09-10 01:08:25 +02:00
parent f8f6fa9fc1
commit 185e910246
8 changed files with 243 additions and 1 deletions

39
mach/mips/libem/aar4.s Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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

View file

@ -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