# Support macros for the Hitachi H8 assembly test cases. ; Set up a minimal machine state .macro start .equ h8300, 0 .equ h8300h, 1 .equ h8300s, 2 .equ h8sx, 3 .if (sim_cpu == h8300s) .h8300s .else .if (sim_cpu == h8300h) .h8300h .else .if (sim_cpu == h8sx) .h8300sx .endif .endif .endif .text .align 2 .global _start _start: jmp _main .data .align 2 .global pass_str .global fail_str .global ok_str .global pass_loc .global fail_loc .global ok_loc pass_str: .ascii "pass\n" fail_str: .ascii "fail\n" ok_str: .ascii "ok\n" pass_loc16: .word pass_str pass_loc32: .long pass_str fail_loc16: .word fail_str fail_loc32: .long fail_str ok_loc16: .word ok_str ok_loc32: .long ok_str .text .global _write_and_exit _write_and_exit: ;ssize_t write(int fd, const void *buf, size_t count); ;Integer arguments have to be zero extended. .if (sim_cpu) #if __INT_MAX__ == 32767 extu.l er0 #endif .endif jsr @@0xc7 mov #0, r0 jmp _exit .global _exit _exit: mov.b r0l, r0h mov.w #0xdead, r1 mov.w #0xbeef, r2 sleep .global _main _main: .endm ; Exit with an exit code .macro exit code mov.w #\code, r0 jmp _exit .endm ; Output "pass\n" .macro pass mov.w #0, r0 ; fd == stdout .if (sim_cpu == h8300) mov.w #pass_str, r1 ; buf == "pass\n" mov.w #5, r2 ; len == 5 .else mov.l #pass_str, er1 ; buf == "pass\n" mov.l #5, er2 ; len == 5 .endif jmp _write_and_exit .endm ; Output "fail\n" .macro fail mov.w #0, r0 ; fd == stdout .if (sim_cpu == h8300) mov.w #fail_str, r1 ; buf == "fail\n" mov.w #5, r2 ; len == 5 .else mov.l #fail_str, er1 ; buf == "fail\n" mov.l #5, er2 ; len == 5 .endif jmp _write_and_exit .endm ; Load an 8-bit immediate value into a general register ; (reg must be r0l - r7l or r0h - r7h) .macro mvi_h_gr8 val reg mov.b #\val, \reg .endm ; Load a 16-bit immediate value into a general register ; (reg must be r0 - r7) .macro mvi_h_gr16 val reg mov.w #\val, \reg .endm ; Load a 32-bit immediate value into a general register ; (reg must be er0 - er7) .macro mvi_h_gr32 val reg mov.l #\val, \reg .endm ; Test the value of an 8-bit immediate against a general register ; (reg must be r0l - r7l or r0h - r7h) .macro test_h_gr8 val reg cmp.b #\val, \reg beq .Ltest_gr8\@ fail .Ltest_gr8\@: .endm ; Test the value of a 16-bit immediate against a general register ; (reg must be r0 - r7) .macro test_h_gr16 val reg h=h l=l .if (sim_cpu == h8300) test_h_gr8 (\val >> 8) \reg\h test_h_gr8 (\val & 0xff) \reg\l .else cmp.w #\val, \reg beq .Ltest_gr16\@ fail .Ltest_gr16\@: .endif .endm ; Test the value of a 32-bit immediate against a general register ; (reg must be er0 - er7) .macro test_h_gr32 val reg cmp.l #\val, \reg beq .Ltest_gr32\@ fail .Ltest_gr32\@: .endm ; Set a general register to the fixed pattern 'a5a5a5a5' .macro set_gr_a5a5 reg .if (sim_cpu == 0) ; h8300 mov.w #0xa5a5, r\reg .else mov.l #0xa5a5a5a5, er\reg .endif .endm ; Set all general registers to the fixed pattern 'a5a5a5a5' .macro set_grs_a5a5 .if (sim_cpu == 0) ; h8300 mov.w #0xa5a5, r0 mov.w #0xa5a5, r1 mov.w #0xa5a5, r2 mov.w #0xa5a5, r3 mov.w #0xa5a5, r4 mov.w #0xa5a5, r5 mov.w #0xa5a5, r6 mov.w #0xa5a5, r7 .else mov.l #0xa5a5a5a5, er0 mov.l #0xa5a5a5a5, er1 mov.l #0xa5a5a5a5, er2 mov.l #0xa5a5a5a5, er3 mov.l #0xa5a5a5a5, er4 mov.l #0xa5a5a5a5, er5 mov.l #0xa5a5a5a5, er6 mov.l #0xa5a5a5a5, er7 .endif .endm ; Test that a general register contains the fixed pattern 'a5a5a5a5' .macro test_gr_a5a5 reg .if (sim_cpu == 0) ; h8300 test_h_gr16 0xa5a5 r\reg .else test_h_gr32 0xa5a5a5a5 er\reg .endif .endm ; Test that all general regs contain the fixed pattern 'a5a5a5a5' .macro test_grs_a5a5 test_gr_a5a5 0 test_gr_a5a5 1 test_gr_a5a5 2 test_gr_a5a5 3 test_gr_a5a5 4 test_gr_a5a5 5 test_gr_a5a5 6 test_gr_a5a5 7 .endm ; Set condition code register to an explicit value .macro set_ccr val ldc #\val, ccr .endm ; Set all condition code flags to zero .macro set_ccr_zero ldc #0, ccr .endm ; Set carry flag to value .macro set_carry_flag val .data scf\@: .byte 0 .text mov.b r0l, @scf\@ mov.b #\val:8, r0l or.b r0l, r0l beq .Lccf\@ ; clear stc ccr, r0l ; set or.b #0x1, r0l jmp .Lecf\@ .Lccf\@: ; clear stc ccr, r0l and.b #0xfe, r0l .Lecf\@: ldc r0l, ccr mov @scf\@, r0l .endm ; Test that carry flag is clear .macro test_carry_clear bcc .Lcc\@ fail ; carry flag not clear .Lcc\@: .endm ; Test that carry flag is set .macro test_carry_set bcs .Lcs\@ fail ; carry flag not clear .Lcs\@: .endm ; Test that overflow flag is clear .macro test_ovf_clear bvc .Lvc\@ fail ; overflow flag not clear .Lvc\@: .endm ; Test that overflow flag is set .macro test_ovf_set bvs .Lvs\@ fail ; overflow flag not clear .Lvs\@: .endm ; Test that zero flag is clear .macro test_zero_clear bne .Lne\@ fail ; zero flag not clear .Lne\@: .endm ; Test that zero flag is set .macro test_zero_set beq .Leq\@ fail ; zero flag not clear .Leq\@: .endm ; Test that neg flag is clear .macro test_neg_clear bpl .Lneg\@ fail ; negative flag not clear .Lneg\@: .endm ; Test that neg flag is set .macro test_neg_set bmi .Lneg\@ fail ; negative flag not clear .Lneg\@: .endm ; Test ccr against an explicit value .macro test_ccr val .data tccr\@: .byte 0 .text mov.b r0l, @tccr\@ stc ccr, r0l cmp.b #\val, r0l bne .Ltcc\@ fail .Ltcc\@: mov.b @tccr\@, r0l .endm ; Test that all (accessable) condition codes are clear .macro test_cc_clear test_carry_clear test_ovf_clear test_zero_clear test_neg_clear ; leaves H, I, U, and UI untested .endm ; Compare memory, fail if not equal (h8sx only, len > 0). .macro memcmp src dst len mov.l #\src, er5 mov.l #\dst, er6 mov.l #\len, er4 .Lmemcmp_\@: cmp.b @er5+, @er6+ beq .Lmemcmp2_\@ fail .Lmemcmp2_\@: dec.l #1, er4 bne .Lmemcmp_\@ .endm