diff --git a/mach/mips/libem/aar4.s b/mach/mips/libem/aar4.s index fc1068f48..b9873300e 100644 --- a/mach/mips/libem/aar4.s +++ b/mach/mips/libem/aar4.s @@ -6,25 +6,33 @@ * Stack: ( array-adr index descriptor-adr -- element-adr ) * Sets r2 = size of element for .los4, .sts4 * Preserves r25 (the last volatile register) + * + * An array descriptor is: + * + * +0 lower bound + * +4 range (upper bound - lower bound) + * +8 element size */ .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 r5, 4(sp) ! r5 = index + lw r6, 8(sp) ! r6 = address of array - lw r7, 0(r4) ! at = lower bound - slt at, r7, at ! at = r5 < at + lw r7, 0(r4) ! r7 = lower bound + slt at, r5, r7 ! at = index < lower bound bne at, zero, .trap_earray + nop + subu r5, r5, r7 ! adjust index for non-zero lower bound - lw at, 4(r4) ! at = upper bound - slt at, at, r5 ! at = at < r5 - bne at, zero, .trap_earray + lw at, 4(r4) ! at = range + slt at, r5, at ! at = adjusted index < range + beq at, zero, .trap_earray + nop 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 diff --git a/tests/plat/core/aar_e.e b/tests/plat/core/aar_e.e new file mode 100644 index 000000000..bd8230d7a --- /dev/null +++ b/tests/plat/core/aar_e.e @@ -0,0 +1,76 @@ +# + mes 2, EM_WSIZE, EM_PSIZE + +/* + * Does basic testing of aar. Unfortunately, aar throws ERANGE on + * error, which we can't catch (or at least, the platforms I've looked at + * don't allow it to be caught, those platforms which actually throw it on + * error). So we just test the non-throwing cases, not the negative ones. + */ + +array + bss 3*EM_WSIZE, 0, 0 + +descriptor + con -1 ; lower bound + con 3 ; range + con EM_WSIZE ; size of element + + + exp $_m_a_i_n + pro $_m_a_i_n, 0 + + /* Access element -1 */ + + lae array + loc -1 + lae descriptor + aar EM_WSIZE + + lae array + cmu EM_WSIZE + zeq *1 + + loc __LINE__ + cal $fail + ass EM_WSIZE +1 + + /* Access element 0 */ + + lae array + loc 0 + lae descriptor + aar EM_WSIZE + + lae array + adp EM_WSIZE + cmu EM_WSIZE + zeq *2 + + loc __LINE__ + cal $fail + ass EM_WSIZE +2 + + /* Access element 1 */ + + lae array + loc 1 + lae descriptor + aar EM_WSIZE + + lae array + adp EM_WSIZE*2 + cmu EM_WSIZE + zeq *3 + + loc __LINE__ + cal $fail + ass EM_WSIZE +3 + + cal $finished + + end +