Changeset View
Changeset View
Standalone View
Standalone View
tests/sys/compat32/aarch64/swp_cond_test_impl.S
- This file was added.
/* | |||||
* SPDX-License-Identifier: BSD-2-Clause | |||||
* | |||||
* Copyright (c) 2021 Warner Losh | |||||
* Copyright (c) 2023 Stormshield | |||||
* Copyright (c) 2023 Klara, Inc. | |||||
*/ | |||||
#include <sys/syscall.h> | |||||
#define STDOUT_FILENO 1 | |||||
#define SWP_MAGIC 0xffc0 | |||||
#define SWPB_MAGIC 0xc0c0 | |||||
.text | |||||
.file "swp_test.S" | |||||
.syntax unified | |||||
.globl main | |||||
.p2align 2 | |||||
.type main,%function | |||||
.code 32 | |||||
main: | |||||
sub sp, #0x04 | |||||
/* r4 is our failed test counter */ | |||||
mov r4, #0 | |||||
/* r6 is our current teset counter */ | |||||
mov r6, #1 | |||||
movw r0, :lower16:.L.testheader | |||||
movt r0, :upper16:.L.testheader | |||||
ldr r1, =(.L.testheaderEnd - .L.testheader - 1) | |||||
bl print | |||||
/* eq */ | |||||
bl reset | |||||
mov r1, #SWP_MAGIC | |||||
cmp r1, r1 | |||||
swpeq r0, r1, [r0] | |||||
bl expect_success | |||||
/* Returned 0 (bad) or 1 (ok) */ | |||||
cmp r0, #0 | |||||
beq 1f | |||||
/* !eq */ | |||||
bl reset | |||||
mov r1, #SWP_MAGIC | |||||
mov r2, #0 | |||||
cmp r1, r2 | |||||
swpeq r0, r1, [r0] | |||||
bl expect_fail | |||||
/* Don't care about the return of the second one, just print */ | |||||
1: | |||||
movw r0, :lower16:.L.eq | |||||
movt r0, :upper16:.L.eq | |||||
ldr r1, =(.L.eqEnd - .L.eq - 1) | |||||
bl print_result | |||||
add r6, r6, #1 /* Next test */ | |||||
/* cs */ | |||||
bl reset | |||||
mov r1, #SWP_MAGIC | |||||
movw r3, #0xffff | |||||
movt r3, #0xffff | |||||
/* Overflow */ | |||||
adds r2, r3, r3 | |||||
swpcs r0, r1, [r0] | |||||
bl expect_success | |||||
/* Returned 0 (bad) or 1 (ok) */ | |||||
cmp r0, #0 | |||||
beq 2f | |||||
/* !cs */ | |||||
bl reset | |||||
mov r1, #SWP_MAGIC | |||||
mov r3, #0x00 | |||||
adds r2, r3, #0x08 | |||||
swpcs r0, r1, [r0] | |||||
bl expect_fail | |||||
/* Don't care about the return of the second one, just print */ | |||||
2: | |||||
movw r0, :lower16:.L.cs | |||||
movt r0, :upper16:.L.cs | |||||
ldr r1, =(.L.csEnd - .L.cs - 1) | |||||
bl print_result | |||||
add r6, r6, #1 /* Next test */ | |||||
/* mi */ | |||||
bl reset | |||||
mov r1, #SWP_MAGIC | |||||
mov r2, #0 | |||||
/* Underflow */ | |||||
subs r2, r2, #0x05 | |||||
swpmi r0, r1, [r0] | |||||
bl expect_success | |||||
/* Returned 0 (bad) or 1 (ok) */ | |||||
cmp r0, #0 | |||||
beq 3f | |||||
/* !mi */ | |||||
bl reset | |||||
mov r1, #SWP_MAGIC | |||||
mov r2, #0x10 | |||||
subs r2, r2, #0x08 | |||||
swpmi r0, r1, [r0] | |||||
bl expect_fail | |||||
/* Don't care about the return of the second one, just print */ | |||||
3: | |||||
movw r0, :lower16:.L.mi | |||||
movt r0, :upper16:.L.mi | |||||
ldr r1, =(.L.miEnd - .L.mi - 1) | |||||
bl print_result | |||||
add r6, r6, #1 /* Next test */ | |||||
/* vs */ | |||||
bl reset | |||||
mov r1, #SWP_MAGIC | |||||
movw r3, #0xffff | |||||
movt r3, #0x7fff | |||||
/* Overflow */ | |||||
adds r2, r3, #0x10 | |||||
swpvs r0, r1, [r0] | |||||
bl expect_success | |||||
/* Returned 0 (bad) or 1 (ok) */ | |||||
cmp r0, #0 | |||||
beq 4f | |||||
/* !vs */ | |||||
bl reset | |||||
mov r1, #SWP_MAGIC | |||||
mov r3, #0x00 | |||||
adds r2, r3, #0x08 | |||||
swpvs r0, r1, [r0] | |||||
bl expect_fail | |||||
/* Don't care about the return of the second one, just print */ | |||||
4: | |||||
movw r0, :lower16:.L.vs | |||||
movt r0, :upper16:.L.vs | |||||
ldr r1, =(.L.vsEnd - .L.vs - 1) | |||||
bl print_result | |||||
add r6, r6, #1 /* Next test */ | |||||
/* hi */ | |||||
bl reset | |||||
mov r1, #SWP_MAGIC | |||||
mov r2, #0x00 | |||||
mov r3, #0x01 | |||||
cmp r3, r2 | |||||
swphi r0, r1, [r0] | |||||
bl expect_success | |||||
/* Returned 0 (bad) or 1 (ok) */ | |||||
cmp r0, #0 | |||||
beq 5f | |||||
/* !hi */ | |||||
bl reset | |||||
mov r1, #SWP_MAGIC | |||||
mov r2, #0x00 | |||||
mov r3, #0x01 | |||||
cmp r2, r3 | |||||
swphi r0, r1, [r0] | |||||
bl expect_fail | |||||
/* Don't care about the return of the second one, just print */ | |||||
5: | |||||
movw r0, :lower16:.L.hi | |||||
movt r0, :upper16:.L.hi | |||||
ldr r1, =(.L.hiEnd - .L.hi - 1) | |||||
bl print_result | |||||
add r6, r6, #1 /* Next test */ | |||||
/* ge */ | |||||
bl reset | |||||
mov r1, #SWP_MAGIC | |||||
mov r2, #0x01 | |||||
cmp r2, r2 | |||||
swpge r0, r1, [r0] | |||||
bl expect_success | |||||
/* Returned 0 (bad) or 1 (ok) */ | |||||
cmp r0, #0 | |||||
beq 6f | |||||
/* !ge */ | |||||
bl reset | |||||
mov r1, #SWP_MAGIC | |||||
mov r2, #0x00 | |||||
mov r3, #0x01 | |||||
cmp r2, r3 | |||||
swpge r0, r1, [r0] | |||||
bl expect_fail | |||||
/* Don't care about the return of the second one, just print */ | |||||
6: | |||||
movw r0, :lower16:.L.ge | |||||
movt r0, :upper16:.L.ge | |||||
ldr r1, =(.L.geEnd - .L.ge - 1) | |||||
bl print_result | |||||
add r6, r6, #1 /* Next test */ | |||||
/* gt */ | |||||
bl reset | |||||
mov r1, #SWP_MAGIC | |||||
mov r2, #0x00 | |||||
mov r3, #0x01 | |||||
cmp r3, r2 | |||||
swpgt r0, r1, [r0] | |||||
bl expect_success | |||||
/* Returned 0 (bad) or 1 (ok) */ | |||||
cmp r0, #0 | |||||
beq 7f | |||||
/* !ge */ | |||||
bl reset | |||||
mov r1, #SWP_MAGIC | |||||
mov r2, #0x00 | |||||
mov r3, #0x01 | |||||
cmp r2, r3 | |||||
swpgt r0, r1, [r0] | |||||
bl expect_fail | |||||
/* Don't care about the return of the second one, just print */ | |||||
7: | |||||
movw r0, :lower16:.L.gt | |||||
movt r0, :upper16:.L.gt | |||||
ldr r1, =(.L.gtEnd - .L.gt - 1) | |||||
bl print_result | |||||
add r6, r6, #1 /* Next test */ | |||||
mov r0, r4 /* retval */ | |||||
ldr r7, =SYS_exit | |||||
swi 0 | |||||
.p2align 2 | |||||
.type print_result,%function | |||||
.code 32 | |||||
print_result: | |||||
push {r4, r5, lr} | |||||
/* Save the label, size for our result */ | |||||
mov r4, r0 | |||||
mov r5, r1 | |||||
movw r0, :lower16:.L.ok | |||||
movt r0, :upper16:.L.ok | |||||
ldr r1, =(.L.okEnd - .L.ok - 1) | |||||
bl print | |||||
mov r0, r6 | |||||
add r0, #0x30 /* "0" + test number */ | |||||
mov r1, #0x01 | |||||
str r0, [sp] | |||||
mov r0, sp | |||||
bl print | |||||
movw r0, :lower16:.L.swp | |||||
movt r0, :upper16:.L.swp | |||||
ldr r1, =(.L.swpEnd - .L.swp - 1) | |||||
bl print | |||||
mov r0, r4 | |||||
mov r1, r5 | |||||
bl print | |||||
movw r0, :lower16:.L.term | |||||
movt r0, :upper16:.L.term | |||||
ldr r1, =(.L.termEnd - .L.term - 1) | |||||
bl print | |||||
pop {r4, r5, lr} | |||||
bx lr | |||||
.p2align 2 | |||||
.type reset,%function | |||||
.code 32 | |||||
reset: | |||||
/* Reset sp[0] and return the address used */ | |||||
mov r0, #0x03 | |||||
str r0, [sp] | |||||
mov r0, sp | |||||
bx lr | |||||
.p2align 2 | |||||
.type expect_fail,%function | |||||
.code 32 | |||||
expect_fail: | |||||
/* Just check the stack value */ | |||||
ldr r0, [sp] | |||||
mov r1, #0x03 | |||||
cmp r0, r1 | |||||
bne 1f | |||||
/* Success (not swapped) */ | |||||
mov r0, #1 | |||||
bx lr | |||||
1: | |||||
/* Fail (swapped) */ | |||||
/* Print the "not" part */ | |||||
movw r0, :lower16:.L.not | |||||
movt r0, :upper16:.L.not | |||||
ldr r1, =(.L.notEnd - .L.not - 1) | |||||
push {lr} | |||||
bl print | |||||
pop {lr} | |||||
/* Failed */ | |||||
add r4, r4, #1 | |||||
mov r0, #0 | |||||
bx lr | |||||
.p2align 2 | |||||
.type expect_success,%function | |||||
.code 32 | |||||
expect_success: | |||||
/* Old value should be 3 */ | |||||
cmp r0, #0x03 | |||||
beq 1f | |||||
b 3f | |||||
1: | |||||
/* Check stack value */ | |||||
ldr r0, [sp] | |||||
mov r1, #SWP_MAGIC | |||||
cmp r0, r1 | |||||
beq 2f | |||||
b 3f | |||||
2: | |||||
mov r0, #1 | |||||
bx lr | |||||
3: | |||||
/* Print the "not" part */ | |||||
movw r0, :lower16:.L.not | |||||
movt r0, :upper16:.L.not | |||||
ldr r1, =(.L.notEnd - .L.not - 1) | |||||
push {lr} | |||||
bl print | |||||
pop {lr} | |||||
/* Failed */ | |||||
add r4, r4, #1 | |||||
mov r0, #0 | |||||
bx lr | |||||
.p2align 2 | |||||
.type print,%function | |||||
.code 32 | |||||
print: | |||||
/* r0 - string, r1 = size */ | |||||
mov r2, r1 | |||||
mov r1, r0 | |||||
ldr r0, =STDOUT_FILENO | |||||
ldr r7, =SYS_write | |||||
swi 0 | |||||
bx lr | |||||
.L.testheader: | |||||
.asciz "1..7\n" | |||||
.L.testheaderEnd: | |||||
.size .L.testheader, .L.testheaderEnd - .L.testheader | |||||
.L.not: | |||||
.asciz "not " | |||||
.L.notEnd: | |||||
.size .L.not, .L.notEnd - .L.not | |||||
.L.ok: | |||||
.asciz "ok " | |||||
.L.okEnd: | |||||
.size .L.ok, .L.okEnd - .L.ok | |||||
.L.swp: | |||||
.asciz " - swp" | |||||
.L.swpEnd: | |||||
.size .L.swp, .L.swpEnd - .L.swp | |||||
.L.eq: | |||||
.asciz "eq" | |||||
.L.eqEnd: | |||||
.size .L.eq, .L.eqEnd - .L.eq | |||||
.L.cs: | |||||
.asciz "cs" | |||||
.L.csEnd: | |||||
.size .L.cs, .L.csEnd - .L.cs | |||||
.L.mi: | |||||
.asciz "mi" | |||||
.L.miEnd: | |||||
.size .L.mi, .L.miEnd - .L.mi | |||||
.L.vs: | |||||
.asciz "vs" | |||||
.L.vsEnd: | |||||
.size .L.vs, .L.vsEnd - .L.vs | |||||
.L.hi: | |||||
.asciz "hi" | |||||
.L.hiEnd: | |||||
.size .L.hi, .L.hiEnd - .L.hi | |||||
.L.ge: | |||||
.asciz "ge" | |||||
.L.geEnd: | |||||
.size .L.ge, .L.geEnd - .L.ge | |||||
.L.gt: | |||||
.asciz "gt" | |||||
.L.gtEnd: | |||||
.size .L.gt, .L.gtEnd - .L.gt | |||||
.L.term: | |||||
.asciz "\n" | |||||
.L.termEnd: | |||||
.size .L.term, .L.termEnd - .L.term |