From 040220acee76f1550e51d01bb5959c2784071398 Mon Sep 17 00:00:00 2001 From: Danny Milosavljevic Date: Sat, 6 Jun 2020 19:51:45 +0200 Subject: [PATCH] Add ARM backend. * build-aux/build-guile.sh: Add ARM backend. * lib/arm-mes/arm.M1: New file. * module/mescc/armv4/as.scm: New file. * module/mescc/armv4/info.scm: New file. * module/mescc/mescc.scm: Use it. * module/mescc/M1.scm (info->M1): Support ARM symbolic instructions, including little endian instructions. Align functions. --- build-aux/build-guile.sh | 2 + lib/arm-mes/arm.M1 | 390 ++++++++++++++++++++++ module/mescc/M1.scm | 15 +- module/mescc/armv4/as.scm | 636 ++++++++++++++++++++++++++++++++++++ module/mescc/armv4/info.scm | 62 ++++ module/mescc/mescc.scm | 1 + 6 files changed, 1105 insertions(+), 1 deletion(-) create mode 100644 lib/arm-mes/arm.M1 create mode 100644 module/mescc/armv4/as.scm create mode 100644 module/mescc/armv4/info.scm diff --git a/build-aux/build-guile.sh b/build-aux/build-guile.sh index bd304509..4cee61e5 100755 --- a/build-aux/build-guile.sh +++ b/build-aux/build-guile.sh @@ -34,6 +34,8 @@ module/mescc/M1.scm module/mescc/as.scm module/mescc/bytevectors.scm module/mescc/compile.scm +module/mescc/armv4/as.scm +module/mescc/armv4/info.scm module/mescc/i386/as.scm module/mescc/i386/info.scm module/mescc/x86_64/as.scm diff --git a/lib/arm-mes/arm.M1 b/lib/arm-mes/arm.M1 new file mode 100644 index 00000000..676e6971 --- /dev/null +++ b/lib/arm-mes/arm.M1 @@ -0,0 +1,390 @@ +### GNU Mes --- Maxwell Equations of Software +### Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen +### Copyright © 2019,2020 Danny Milosavljevic +### +### This file is part of GNU Mes. +### +### Mes is free software# you can redistribute it and/or modify it +### under the terms of the GNU General Public License as published by +### the Free Software Foundation# either version 3 of the License, or (at +### your option) any later version. +### +### GNU Mes is distributed in the hope that it will be useful, but +### WITHOUT ANY WARRANTY# without even the implied warranty of +### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +### GNU General Public License for more details. +### +### You should have received a copy of the GNU General Public License +### along with GNU Mes. If not, see . + +# Note: r9 is used as scratch register and is assumed to not contain anything important! + +# reduced instruction set: r0, r1 (some r2 for shift, r3 for mul) + +# The "e" in most opcodes near the end means "always". +# 020090e0 # adds r0, r0, r2; ADDS = '0' op3 op1 '09' op2 'e0' +# 030091e0 # adds r0, r1, r3 +# 031091e0 # adds r1, r1, r3 +# 030090e0 # adds r0, r0, r3 +DEFINE add____$i8,%r0 0090e2 # adds r0, r0, #xx; ADDSI = immediate op1 '09' op2 'e2' +# 0091e2 # adds r0, r1, #xx; ADDSI = immediate op1 '09' op2 'e2' +# 1090e2 # adds r1, r0, #xx; ADDSI = immediate op1 '09' op2 'e2' +DEFINE add____$i8,%r1 1091e2 # adds r1, r1, #xx +DEFINE add____$i8,%r13 d09de2 # adds r13, r13, #xx +DEFINE sub____$i8,%r0 0050e2 # subs r0, r0, #xx +DEFINE sub____$i8,%r1 1051e2 # subs r1, r1, #xx +DEFINE add____%r0,%r0 000090e0 # adds r0, r0, r0 +DEFINE add____%r0,%r1 001091e0 # adds r1, r1, r0 +DEFINE add____%r1,%r0 010090e0 # adds r0, r0, r1 +DEFINE add____%r1,%r1 011091e0 # adds r1, r1, r1 +DEFINE and____%r1,%r0 010010e0 # ands r0, r0, r1 +DEFINE and____$i8,%r0 0000e2 +DEFINE and____$i8,%r1 1001e2 +DEFINE call___*%r0 30ff2fe1 +DEFINE call___*%r1 31ff2fe1 +DEFINE cmp____$i8,%r0 0050e3 +DEFINE cmp____$i8,%r1 0051e3 +DEFINE cmn____$i8,%r0 0070e3 +DEFINE cmn____$i8,%r1 0071e3 +DEFINE swi____$0 000000ef +DEFINE ja 8a +DEFINE jae 3a +DEFINE jb 2a +DEFINE jbe 9a +DEFINE je 0a +DEFINE jg ca +DEFINE jge aa +DEFINE jl ba +DEFINE jle da +DEFINE jne 1a + +# e3a00064 mov r0, #100 +# e3a01064 mov r1, #100 +# e3a02064 mov r2, #100 + +# 0: e3047215 movw r7, #16917 ; 0x4215 + +# OK: +DEFINE mov____$i8,%r0 00a0e3 +DEFINE mov____$i8,%r1 10a0e3 +DEFINE mov____$i8,%r7 70a0e3 + +DEFINE mvn____%r0,$i8 00e0e3 +DEFINE mvn____%r1,$i8 10e0e3 +DEFINE mvn____%r7,$i8 70e0e3 + +DEFINE mov____%r0,%r1 0010a0e1 +DEFINE mov____%r0,%r2 0020a0e1 +DEFINE mov____%fp,%r1 0b10a0e1 +DEFINE mov____%fp,%r2 0b20a0e1 +DEFINE mov____%r0,(%r1) 000081e5 +DEFINE mov____%r1,%r0 0100a0e1 +DEFINE mov____%r1,%r2 0120a0e1 +DEFINE mov____%esp,%r0 0d00a0e1 + +# e59f9004 ldr r9, [pc, #4] ; +# e5890000 str r0, [r9] +# ea000000 b L2 +# L1: ??? +# L2: +DEFINE mov____%r0,0x32 04909fe5000089e5000000ea +DEFINE mov____%r1,0x32 04909fe5001089e5000000ea +DEFINE mov____%r2,0x32 04909fe5002089e5000000ea + +# e92d0005 push {r0, r2} +# e5910000 ldr r0, [r1] +# e59f200c ldr r2, [pc, #12] ; 1c +# e0800002 add r0, r0, r2 +# e5810000 str r0, [r1] +# e8bd0005 pop {r0, r2} +# ea000000 b 20 +# X2: ??? +# Y2: +DEFINE add____$i32,(%r1) 05002de9000091e50c209fe5020080e0000081e50500bde8000000ea + +# e59f0000 ldr r0, [pc] +# ea000000 b c +# nop +# R: +DEFINE mov____$i32,%r0 00009fe5000000ea +DEFINE mov____$i32,%r1 00109fe5000000ea +DEFINE mov____$i32,%r2 00209fe5000000ea +DEFINE mov____$i32,%r7 00709fe5000000ea +DEFINE mov____%r2,(%r1) 002081e5 +DEFINE mov____%r3,%r0 0300a0e1 +DEFINE mov____%r3,%r1 0e10a0e1 +DEFINE mov____(%r0),%r0 000090e5 +DEFINE mov____(%r0),%r2 002090e5 +DEFINE mov____(%r1),%r1 001091e5 + +DEFINE nop 0000a0e1 +DEFINE not____%r0 0000e0e1 +DEFINE not____%r1 0110e0e1 +DEFINE or_____%r1,%r0 010090e1 # orrs r0, r0, r1 +DEFINE pop____%r0 04009de4 +DEFINE pop____%r1 04109de4 +DEFINE pop____%r3 04309de4 +DEFINE pop____%lr 04e09de4 + +# e59f9004 ldr r9, [pc, #4] ; c +# e52d9004 push {r9} ; (str r9, [sp, #-4]!) +# ea000000 b 10 +# L1x: data +# L1y: + +DEFINE push___$i32 04909fe504902de5000000ea + +DEFINE push___%r0 04002de5 # str r0, [sp, #-4]! +DEFINE push___%r1 04102de5 # str r1, [sp, #-4]! +DEFINE push___%r2 04202de5 # str r2, [sp, #-4]! +DEFINE push___%r3 04302de5 # str r3, [sp, #-4]! +DEFINE push___%lr 04e02de5 # str lr, [sp, #-4]! + +DEFINE sub____%r1,%r0 010050e0 # subs r0, r0, r1 +DEFINE test___%r0,%r0 000010e1 +DEFINE test___%r1,%r1 010011e1 +DEFINE xor____$i8,%r0 0030e2 # eors r0, r0, #xx +DEFINE xor____%r0,%r0 000030e0 # eors r0, r0, r0 +DEFINE xor____%r1,%r0 010030e0 # eors r0, r0, r1 +DEFINE xor____%r1,%r1 011031e0 # eors r1, r1, r1 +DEFINE xor____%r3,%r3 033033e0 # eors r3, r3, r3 + +# Note: These are the native ARM instructions. +# Note: i8 immediate +DEFINE ldr____%r0,(%fp,+#$i8) 009be5 +DEFINE ldr____%r1,(%fp,+#$i8) 109be5 +DEFINE ldr____%r2,(%fp,+#$i8) 209be5 +DEFINE ldr____%r3,(%fp,+#$i8) 309be5 +DEFINE ldr____%r4,(%fp,+#$i8) 409be5 +DEFINE ldr____%r5,(%fp,+#$i8) 509be5 +DEFINE ldr____%r7,(%fp,+#$i8) 709be5 +DEFINE ldr____%fp,(%fp,+#$i8) b09be5 +DEFINE ldr____%sp,(%fp,+#$i8) d09be5 +DEFINE ldr____%lr,(%fp,+#$i8) e09be5 +DEFINE ldr____%r0,(%fp,-#$i8) 001be5 +DEFINE ldr____%r1,(%fp,-#$i8) 101be5 +DEFINE ldr____%r2,(%fp,-#$i8) 201be5 +DEFINE ldr____%r3,(%fp,-#$i8) 301be5 +DEFINE ldr____%r4,(%fp,-#$i8) 401be5 +DEFINE ldr____%r5,(%fp,-#$i8) 501be5 +DEFINE ldr____%r7,(%fp,-#$i8) 701be5 +DEFINE ldr____%fp,(%fp,-#$i8) b01be5 +DEFINE ldr____%sp,(%fp,-#$i8) d01be5 +DEFINE ldr____%lr,(%fp,-#$i8) e01be5 +DEFINE str____%r0,(%fp,+#$i8) 008be5 +DEFINE str____%r1,(%fp,+#$i8) 108be5 +DEFINE str____%r2,(%fp,+#$i8) 208be5 +DEFINE str____%r3,(%fp,+#$i8) 308be5 +DEFINE str____%r4,(%fp,+#$i8) 408be5 +DEFINE str____%r5,(%fp,+#$i8) 508be5 +DEFINE str____%r7,(%fp,+#$i8) 708be5 +DEFINE str____%fp,(%fp,+#$i8) b08be5 +DEFINE str____%sp,(%fp,+#$i8) d08be5 +DEFINE str____%lr,(%fp,+#$i8) e08be5 +DEFINE str____%r0,(%fp,-#$i8) 000be5 +DEFINE str____%r1,(%fp,-#$i8) 100be5 +DEFINE str____%r2,(%fp,-#$i8) 200be5 +DEFINE str____%r3,(%fp,-#$i8) 300be5 +DEFINE str____%r4,(%fp,-#$i8) 400be5 +DEFINE str____%r5,(%fp,-#$i8) 500be5 +DEFINE str____%r7,(%fp,-#$i8) 700be5 +DEFINE str____%fp,(%fp,-#$i8) b00be5 +DEFINE str____%sp,(%fp,-#$i8) d00be5 +DEFINE str____%lr,(%fp,-#$i8) e00be5 +# Note: Loads INTO register r0 (ARM original operand order) +DEFINE ldrsb__%r0,(%r0) d000d0e1 # ldrsb r0, [r0] +DEFINE ldrsb__%r1,(%r1) d010d1e1 # ldrsb r1, [r1] +DEFINE ldrsb__%r2,(%r2) d020d2e1 # ldrsb r2, [r2] +DEFINE ldrsb__%r3,(%r3) d030d3e1 # ldrsb r3, [r3] +DEFINE ldrsb__%r4,(%r4) d040d4e1 # ldrsb r4, [r4] +DEFINE ldrsb__%r5,(%r5) d050d5e1 # ldrsb r5, [r5] +DEFINE ldrb___%r0,(%r1) 0000d1e5 # ldrb r0, [r1] +DEFINE ldrh___%r0,(%r0) b000d0e1 # ldrh r0, [r0] +DEFINE ldrh___%r0,(%r1) b000d1e1 # ldrh r0, [r1] +DEFINE ldrh___%r1,(%r1) b010d1e1 # ldrh r1, [r1] +DEFINE ldrh___%r2,(%r2) b020d2e1 # ldrh r2, [r2] +DEFINE ldrh___%r3,(%r3) b030d3e1 # ldrh r3, [r3] +DEFINE strb___%r0,(%r0) 0000c0e5 # strb r0, [r0] +DEFINE strb___%r0,(%r1) 0000c1e5 # strb r0, [r1] +DEFINE strb___%r1,(%r1) 0010c1e5 # strb r1, [r1] +DEFINE strb___%r2,(%r2) 0020c2e5 # strb r2, [r2] +DEFINE strb___%r3,(%r3) 0030c3e5 # strb r3, [r3] +DEFINE strb___%r4,(%r4) 0040c4e5 # strb r4, [r4] +DEFINE strb___%r0,(%fp,+#$i8) 00cbe5 # strb r0, [fp, +#xx] +DEFINE strb___%r0,(%fp,-#$i8) 004be5 # strb r0, [fp, -#xx] +DEFINE strh___%r0,(%r0) b000c0e1 # strh r0, [r0] +DEFINE strh___%r0,(%r1) b000c1e1 # strh r0, [r1] +DEFINE strh___%r1,(%r1) b010c1e1 # strh r1, [r1] +DEFINE strh___%r2,(%r2) b020c2e1 # strh r2, [r2] +DEFINE strh___%r3,(%r3) b030c3e1 # strh r3, [r3] +DEFINE strh___%r4,(%r4) b040c4e1 # strh r4, [r4] + +# There's a single instruction that does it--but I don't know how to encode it. +# mov %r9, immediate +# add %r9, %r9, %fp +# strh %r0, [%r9] +DEFINE strh___%r0,(%fp,+#$i8) 90a0e30b9089e0b000c9e1 + +# There's a single instruction that does it--but I don't know how to encode it. +# e3a090xx mov %r9, immediate +# e05b9009 sub %r9, %fp, %r9 +# e1c900b0 strh %r0, [%r9] +DEFINE strh___%r0,(%fp,-#$i8) 90a0e309904be0b000c9e1 + +DEFINE movle__%r0,$i8 00a0d3 # movle r0, #xx +DEFINE movlt__%r0,$i8 00a0b3 # movlt r0, #xx +DEFINE movge__%r0,$i8 00a0a3 # movge r0, #xx +DEFINE movgt__%r0,$i8 00a0c3 # movgt r0, #xx +DEFINE movcs__%r0,$i8 00a023 # movcs r0, #xx +DEFINE movcc__%r0,$i8 00a033 # movcc r0, #xx +DEFINE movhi__%r0,$i8 00a083 # movhi r0, #xx +DEFINE moveq__%r0,$i8 00a003 # moveq r0, #xx +DEFINE movle__%r1,$i8 10a0d3 # movle r1, #xx +DEFINE movlt__%r1,$i8 10a0b3 # movlt r1, #xx +DEFINE movge__%r1,$i8 10a0a3 # movge r1, #xx +DEFINE movgt__%r1,$i8 10a0c3 # movgt r1, #xx +DEFINE movcs__%r1,$i8 10a023 # movcs r1, #xx +DEFINE movcc__%r1,$i8 10a033 # movcc r1, #xx +DEFINE movhi__%r1,$i8 10a083 # movhi r1, #xx +DEFINE moveq__%r1,$i8 10a003 # moveq r1, #xx + +DEFINE asr____%r0,%r0,%r1 5001a0e1 # asr %r0, %r0, %r1 +DEFINE lsl____%r0,%r0,%r1 1001a0e1 # lsl %r0, %r0, %r1 +DEFINE lsl____%r0,%r0,$i8 90a0e31009a0e1 # mov r9, #xx; lsl %r0, %r0, %r9 +DEFINE lsl____%r1,%r1,$i8 90a0e31119a0e1 # mov r9, #xx; lsl %r1, %r1, %r9 +DEFINE lsr____%r0,%r0,%r1 3001a0e1 # lsr %r0, %r0, %r1 +DEFINE ldr____%r0,(%sp,#$i8) 009de5 # ldr r0, [r13+xx] +DEFINE ldr____%r1,(%sp,#$i8) 109de5 # ldr r1, [r13+xx] +#DEFINE add____%r2,%r0,%r1,lsl#4 012280e0 +# Without carry +DEFINE add____%r2,%r0,%r1,lsl#2 012180e0 +DEFINE add____%r2,%r1,%r0,lsl#2 002181e0 +DEFINE add____%r1,$i8 1081e2 +DEFINE add____%r2,$i8 2082e2 +DEFINE bl eb +DEFINE b ea +DEFINE sxtb__%r0,%r0 7000afe6 +DEFINE sxtb__%r1,%r1 7110afe6 +DEFINE sxth__%r0,%r0 7000bfe6 +DEFINE sxth__%r1,%r1 7110bfe6 +DEFINE uxtb__%r0,%r0 7000efe6 +DEFINE uxtb__%r1,%r1 7110efe6 +DEFINE uxth__%r0,%r0 7000ffe6 +DEFINE uxth__%r1,%r1 7110ffe6 + +# See: https://github.com/torvalds/linux/blob/v4.19/arch/arm/tools/syscall.tbl +DEFINE SYS_exit 01 +DEFINE SYS_fork 02 +DEFINE SYS_read 03 +DEFINE SYS_write 04 +DEFINE SYS_open 05 +DEFINE SYS_close 06 +# DEFINE SYS_waitpid does_not_exist +DEFINE SYS_rmdir 28 +DEFINE SYS_wait4 72 +# waitid: 0x118 + +DEFINE SYS_unlink 0a +DEFINE SYS_execve 0b +DEFINE SYS_chmod 0f +DEFINE SYS_lseek 13 +DEFINE SYS_access 21 +DEFINE SYS_brk 2d +DEFINE SYS_ioctl 36 +DEFINE SYS_stat 6a +DEFINE SYS_fsync 76 +DEFINE SYS_getcwd b7 + +# These are x86 ABI remnants: + +DEFINE mul____%r1,%r0 910089e0 # umull r0, r9, r1, r0 +DEFINE mul____%r0,%r1 910089e0 # umull r0, r9, r1, r0 +DEFINE mov____%ebp,%r0 0b00a0e1 +DEFINE mov____%ebp,%r1 0b10a0e1 +DEFINE push___%ebp 04b02de5 # str fp, [sp, #-4]! +DEFINE pop____%ebp 04b09de4 # ldr fp, [sp], #4 +DEFINE mov____%esp,%ebp 0db0a0e1 # mov fp, sp +DEFINE mov____%ebp,%esp 0bd0a0e1 # mov sp, fp +DEFINE sub____$i8,%esp d04de2 # sub sp, sp, #xx + +DEFINE jmp____*%r1 11ff2fe1 + +# e59f9008 ldr r9, [pc, #8] ; 10 +# e089900b add r9, r9, fp +# e5890000 str r0, [r9] +# ea000000 b 14 +# 00000010 : data +# 00000014 : +DEFINE mov____%r0,0x32(%ebp) 08909fe50b9089e0000089e5000000ea +DEFINE mov____%r1,0x32(%ebp) 08909fe50b9089e0001089e5000000ea +DEFINE mov____%r2,0x32(%ebp) 08909fe50b9089e0002089e5000000ea + +# e59f9004 ldr r9, [pc, #4] ; c +# e5990000 ldr r0, [r9] +# ea000000 b 10 +DEFINE mov____0x32,%r0 04909fe5000099e5000000ea +DEFINE mov____0x32,%r1 04909fe5001099e5000000ea +DEFINE mov____0x32,%r2 04909fe5002099e5000000ea + +# e1a09000 mov r9, r0 +# e1a00001 mov r0, r1 +# e1a01009 mov r1, r9 +DEFINE xchg___%r0,%r1 0090a0e10100a0e10910a0e1 + +# e49de004 pop {lr} ; (ldr lr, [sp], #4) +# e1a0f00e mov pc, lr +DEFINE ret 04e09de40ef0a0e1 + +# The flags are also updated, but that's probably useless. +DEFINE add____$i8,%esp d09de2 + +# e24ddeff sub sp, sp, #4080 +# e24dd064 sub sp, sp, #100 +DEFINE allocate_stack_4180 ffde4de264d04de2 + +DEFINE mov____0x32(%ebp),%r0 08909fe50b9089e0000099e5000000ea +# e59f9008 ldr r9, [pc, #8] +# e089900b add r9, r9, fp +# e5991000 ldr r1, [r9] +# ea000000 b 20 +# V: ... +# VD: +DEFINE mov____0x32(%ebp),%r1 08909fe50b9089e0001099e5000000ea + +# e1a09000 mov r9, r0 +# e59d0000 ldr r0, [sp] +# e58d9000 str r9, [sp] +DEFINE xchg___%r0,(%esp) 0090a0e100009de500908de5 + +# e52d1004 push {r1} ; (str r1, [sp, #-4]!) +# e59f1010 ldr r1, [pc, #16] ; 1c +# e5909000 ldr r9, [r0] +# e0999001 adds r9, r9, r1 +# e5809000 str r9, [r0] +# e49d1004 pop {r1} ; (ldr r1, [sp], #4) +# ea000000 b 20 +# V: ... +# VD: +DEFINE add____$i32,(%r0) 04102de510109fe5009090e5019099e0009080e504109de4000000ea + +# mov %r9, #00 +# push {%r9} +DEFINE push___0 0090a0e304902de5 + +DEFINE add____$i32,%r0 04909fe5090090e0000000ea +# e59f9004 ldr r9, [pc, #4] ; c +# e0911009 adds r1, r1, r9 +# ea000000 b 10 +# VALUE: +DEFINE add____$i32,%r1 04909fe5091091e0000000ea +DEFINE add____$i32,%r2 04909fe5092092e0000000ea + +# e59f9008 ldr r9, [pc, #8] ; 10 +# e089900b add r9, r9, fp +# e5c90000 strb r0, [r9] +# ea000000 b 14 +# WERT: nop +# WERTD: +DEFINE strb___%r0,0x32(%ebp) 08909fe50b9089e00000c9e5000000ea + +DEFINE wfi 03f020e3 diff --git a/module/mescc/M1.scm b/module/mescc/M1.scm index 66740230..766621e0 100644 --- a/module/mescc/M1.scm +++ b/module/mescc/M1.scm @@ -63,6 +63,13 @@ (define (hex2:offset1 o) (string-append "!" o)) +(define (hex2:offset2 o) + (string-append "@" o)) + +(define (hex2:offset3 o) + "Note: Uses architecture-specific printer (for branch instructions)" + (string-append "^~" o)) + (define hex? #t) (define (hex2:immediate o) @@ -171,6 +178,8 @@ ((#:offset ,offset) (hex2:offset offset)) ((#:offset1 ,offset1) (hex2:offset1 offset1)) + ((#:offset2 ,offset2) (hex2:offset2 offset2)) + ((#:offset3 ,offset3) (hex2:offset3 offset3)) ((#:immediate ,immediate) (hex2:immediate immediate)) ((#:immediate1 ,immediate1) (hex2:immediate1 immediate1)) ((#:immediate2 ,immediate2) (hex2:immediate2 immediate2)) @@ -191,11 +200,15 @@ ((or (string? (car o)) (symbol? (car o))) (display "\t" ) (display-join (map text->M1 o) " ")) + ((or (string? (car (reverse o))) (symbol? (car (reverse o)))) + (display "\t" ) + (display-join (map text->M1 o) " ")) (else (error "line->M1 invalid line:" o))) (newline)) (when verbose? (display (string-append " :" name "\n") (current-error-port))) - (display (string-append "\n\n:" name "\n")) + ;; "<" aligns to multiple of 4 Bytes. + (display (string-append "\n\n<\n:" name "\n")) (for-each line->M1 (apply append text)))) (define (write-global o) (define (labelize o) diff --git a/module/mescc/armv4/as.scm b/module/mescc/armv4/as.scm new file mode 100644 index 00000000..3fb97bbc --- /dev/null +++ b/module/mescc/armv4/as.scm @@ -0,0 +1,636 @@ +;;; GNU Mes --- Maxwell Equations of Software +;;; Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen +;;; Copyright © 2019 Danny Milosavljevic +;;; +;;; This file is part of GNU Mes. +;;; +;;; GNU Mes is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Mes is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Mes. If not, see . + +;;; Commentary: + +;;; define armv4 assembly + +;;; Code: + +(define-module (mescc armv4 as) + #:use-module (mes guile) + #:use-module (mescc as) + #:use-module (mescc info) + #:export ( + armv4:instructions + )) + +(define (armv4:function-preamble . rest) + "Note: Pretends to be on x86 a lot" + '(("push___%lr") + ("push___%ebp") + ("mov____%esp,%ebp"))) + +(define (armv4:function-locals . rest) + `(("allocate_stack_4180"))) ; 4*1024 buf, 20 local vars + +(define (armv4:r->local info n) + (or n (error "invalid value: armv4:r->local: " n)) + (let ((r (get-r info)) + (n (- 0 (* 4 n)))) + `(,`(,(string-append "mov____%" r ",0x32(%ebp)") (#:immediate ,n))))) + +(define (immediate->r0 v) + (if (< (abs v) #x100) + (if (< v 0) + `(((#:immediate1 ,(- -1 v)) "mvn____%r0,$i8")) + `(((#:immediate1 ,v) "mov____$i8,%r0"))) + `(("mov____$i32,%r0" (#:immediate ,v))))) + +(define (armv4:value->r info v) + (let ((r (get-r info))) + (if (< (abs v) #x100) + (if (< v 0) + `(((#:immediate1 ,(- -1 v)) ,(string-append "mvn____%" r ",$i8"))) + `(((#:immediate1 ,v) ,(string-append "mov____$i8,%" r)))) + `((,(string-append "mov____$i32,%" r) (#:immediate ,v)))))) + +(define (armv4:ret . rest) + "Note: Pretends to be on x86 a lot" + '(("mov____%ebp,%esp") + ("pop____%ebp") + ("ret"))) + +(define (armv4:r-zero? info) + (let ((r (get-r info))) + `(((#:immediate1 #x00) ,(string-append "cmp____$i8,%" r))))) + +(define (armv4:local->r info n) + (let ((r (get-r info)) + (n (- 0 (* 4 n)))) + (if (< (abs n) #x100) + (if (< n 0) + `(((#:immediate1 ,(abs n)) + ,(string-append "ldr____%" r ",(%fp,-#$i8)"))) + `(((#:immediate1 ,n) + ,(string-append "ldr____%" r ",(%fp,+#$i8)")))) + `((,(string-append "mov____0x32(%ebp),%" r) (#:immediate ,n)))))) + +(define (armv4:r0+r1 info) + (let ((r0 (get-r0 info)) + (r1 (get-r1 info))) + `((,(string-append "add____%" r1 ",%" r0))))) + +(define (armv4:call-label info label n) + `(((#:offset3 ,label) bl) + ((#:immediate1 ,(* n 4)) "add____$i8,%esp"))) + +(define (armv4:r->arg info i) + (let ((r (get-r info))) + `((,(string-append "push___%" r))))) + +(define (armv4:label->arg info label i) + `(("push___$i32" (#:address ,label)))) + +;; Register--register value subtraction +(define (armv4:r0-r1 info) + (let ((r0 (get-r0 info)) + (r1 (get-r1 info))) + `((,(string-append "sub____%" r1 ",%" r0))))) + +;; Zero flag to register. +(define (armv4:zf->r info) + (let* ((r (get-r info))) + `(((#:immediate1 #x00) ,(string-append "mov____$i8,%" r)) + ((#:immediate1 #x01) ,(string-append "moveq__%" r ",$i8"))))) + +;; C NOT Register value. +(define (armv4:r-negate info) + (armv4:zf->r info)) + +(define (armv4:xor-zf info) + '(((#:immediate1 #x00) "mov____$i8,%r0") + ((#:immediate1 #x01) "moveq__%r0,$i8") + ((#:immediate1 #x00) "cmp____$i8,%r0"))) + +(define (armv4:r->local+n info id n) + (let ((n (+ (- 0 (* 4 id)) n)) + (r (get-r info))) + `(,(if (< (abs n) #x100) + (if (< n 0) + `((#:immediate1 ,(abs n)) + ,(string-append "str____%" r ",(%fp,-#$i8)")) + `((#:immediate1 ,n) + ,(string-append "str____%" r ",(%fp,+#$i8)"))) + `(,(string-append "mov____%" r ",0x32(%ebp)") (#:immediate ,n)))))) + +(define (armv4:r-mem-add info v) + (let ((r (get-r info))) + `((,(string-append "add____$i32,(%" r ")") (#:immediate ,v))))) + +(define (armv4:r-byte-mem-add info v) + (let ((r (get-r info))) + `((,(string-append "push___%r0")) + (,(string-append "ldrb___%r0,(%" r ")")) + ,(if (< v 0) + `((#:immediate1 ,(abs v)) ,(string-append "sub____$i8,%r0")) + `((#:immediate1 ,v) ,(string-append "add____$i8,%r0"))) + (,(string-append "strb___%r0,(%" r ")")) + (,(string-append "pop____%r0"))))) + +(define (armv4:r-word-mem-add info v) + (let ((r (get-r info))) + `((,(string-append "push___%r0")) + (,(string-append "ldrh___%r0,(%" r ")")) + ,(if (< v 0) + `((#:immediate1 ,(abs v)) ,(string-append "sub____$i8,%r0")) + `((#:immediate1 ,v) ,(string-append "add____$i8,%r0"))) + (,(string-append "strh___%r0,(%" r ")")) + (,(string-append "pop____%r0"))))) + +(define (armv4:local-ptr->r info n) + (let ((r (get-r info))) + (let ((n (- 0 (* 4 n)))) + `((,(string-append "mov____%ebp,%" r)) + ,(if (< (abs n) #x100) + (if (< n 0) + `((#:immediate1 ,(abs n)) ,(string-append "sub____$i8,%" r)) + `((#:immediate1 ,n) ,(string-append "add____$i8,%" r))) + `(,(string-append "add____$i32,%" r) (#:immediate ,n))))))) + +(define (armv4:label->r info label) + (let ((r (get-r info))) + `((,(string-append "mov____$i32,%" r) (#:address ,label))))) + +(define (armv4:r0->r1 info) + (let ((r0 (get-r0 info)) + (r1 (get-r1 info))) + `((,(string-append "mov____%" r0 ",%" r1))))) + +(define (armv4:byte-mem->r info) + (let ((r (get-r info))) + `((,(string-append "ldrsb__%" r ",(%" r ")")) + ((#:immediate1 #xFF) ,(string-append "and____$i8,%" r))))) + +(define (armv4:byte-r info) + (let* ((r (get-r info))) + `((,(string-append "uxtb__%" r ",%" r))))) + +(define (armv4:byte-signed-r info) + (let* ((r (get-r info))) + `((,(string-append "sxtb__%" r ",%" r))))) + +(define (armv4:word-r info) + (let* ((r (get-r info))) + `((,(string-append "uxth__%" r ",%" r))))) + +(define (armv4:word-signed-r info) + (let* ((r (get-r info))) + `((,(string-append "sxth__%" r ",%" r))))) + +(define (armv4:jump info label) + `(((#:offset3 ,label) "b"))) + +(define (armv4:jump-z info label) + `(((#:offset3 ,label) "je"))) + +(define (armv4:jump-nz info label) + `(((#:offset3 ,label) "jne"))) + +(define (armv4:jump-byte-z info label) + `(("test___%r0,%r0") ; TODO: 1 Byte ? + ((#:offset3 ,label) "je"))) + +;; signed +(define (armv4:jump-g info label) + `(((#:offset3 ,label) "jg"))) + +(define (armv4:jump-ge info label) + `(((#:offset3 ,label) "jge"))) + +(define (armv4:jump-l info label) + `(((#:offset3 ,label) "jl" ))) + +(define (armv4:jump-le info label) + `(((#:offset3 ,label) "jle"))) + +;; unsigned +(define (armv4:jump-a info label) + `(((#:offset3 ,label) "ja"))) + +(define (armv4:jump-ae info label) + `(((#:offset3 ,label) "jae"))) + +(define (armv4:jump-b info label) + `(((#:offset3 ,label) "jb"))) + +(define (armv4:jump-be info label) + `(((#:offset3 ,label) "jbe"))) + +(define (armv4:byte-r0->r1-mem info) + (let* ((r0 (get-r0 info)) + (r1 (get-r1 info))) + `((,(string-append "strb___%" r0 ",(%" r1 ")"))))) + +(define (armv4:label-mem->r info label) + (let ((r (get-r info))) + `((,(string-append "mov____0x32,%" r) (#:address ,label))))) + +(define (armv4:word-mem->r info) + (let ((r (get-r info))) + `((,(string-append "ldrh___%" r ",(%" r ")"))))) + +(define (armv4:mem->r info) + (let ((r (get-r info))) + `((,(string-append "mov____(%" r "),%" r))))) + +(define (armv4:local-add info n v) + (let ((n (- 0 (* 4 n)))) + (append (immediate->r0 v) + `(("mov____0x32(%ebp),%r1" (#:immediate ,n)) + ("add____%r0,%r1") + ("mov____%r1,0x32(%ebp)" (#:immediate ,n)))))) + +(define (armv4:label-mem-add info label v) + (append (immediate->r0 v) + `(("add____%r0,0x32" (#:address ,label))))) + +(define (armv4:nop info) + '(("nop"))) + +(define (armv4:swap-r0-r1 info) + (let ((r0 (get-r0 info)) + (r1 (get-r1 info))) + `((,(string-append "xchg___%" r0 ",%" r1))))) + +(define (armv4:flag->r branchspec info) + "Find out whether a flag or set of flag has a given set of values and set the value of the register R to 1 if it is so, and to 0 otherwise. + Possible values for branchspec are one of (\"cs\", \"cc\", \"ge\", \"gt\", \"hi\", \"lt\", \"le\")" + (let* ((r (get-r info))) + `(((#:immediate1 #x00) ,(string-append "mov____$i8,%" r)) + ((#:immediate1 #x01) ,(string-append "mov" branchspec "__%" r ",$i8"))))) + +;; signed +(define (armv4:g?->r info) + (armv4:flag->r "gt" info)) + +(define (armv4:ge?->r info) + (armv4:flag->r "ge" info)) + +(define (armv4:l?->r info) + (armv4:flag->r "lt" info)) + +(define (armv4:le?->r info) + (armv4:flag->r "le" info)) + +;; unsigned +(define (armv4:a?->r info) + (armv4:flag->r "hi" info)) + +(define (armv4:ae?->r info) + (armv4:flag->r "cs" info)) + +(define (armv4:b?->r info) + (armv4:flag->r "cc" info)) + +(define (armv4:be?->r info) + (let* ((r (get-r info))) + `(((#:immediate1 #x01) ,(string-append "mov____$i8,%" r)) + ((#:immediate1 #x00) ,(string-append "movhi__%" r ",$i8"))))) + +(define (armv4:test-r info) + (let ((r (get-r info))) + `((,(string-append "test___%" r ",%" r))))) + +(define (armv4:r->label info label) + (let ((r (get-r info))) + `((,(string-append "mov____%" r ",0x32") (#:address ,label))))) + +(define (armv4:r->byte-label info label) + (let* ((r (get-r info))) ; r: byte + `((,(string-append "movb___%" r ",0x32") (#:address ,label))))) + +(define (armv4:r->word-label info label) + (let* ((r (get-r info))) ; r: halfword + `((,(string-append "movw___%" r ",0x32") (#:address ,label))))) + +(define (armv4:call-r info n) + (let ((r (get-r info))) + `((,(string-append "call___*%" r)) + ;; Note: Assumes n > 0. + ((#:immediate1 ,(* n 4)) "add____$i8,%esp")))) + +(define (armv4:r0*r1 info) + ;; FIXME: Signedness. + (let ((r0 (get-r0 info)) + (r1 (get-r1 info))) + `((,(string-append "mul____%" r0 ",%" r1))))) + +(define (armv4:r0<>r1 info) + (let ((r0 (get-r0 info)) + (r1 (get-r1 info))) + `((,(string-append "lsr____%" r0 ",%" r0 ",%" r1))))) + +(define (armv4:r0-and-r1 info) + (let ((r0 (get-r0 info)) + (r1 (get-r1 info))) + `((,(string-append "and____%" r1 ",%" r0))))) + +(define (armv4:r0/r1 info signed?) + (let ((r0 (get-r0 info)) + (r1 (get-r1 info))) + (if signed? + ;; __aeabi_idiv(a, b) + (cons* `(,(string-append "push___%" r1)) + `(,(string-append "push___%" r0)) + (armv4:call-label #f "__aeabi_idiv" 2)) + ;; __mesabi_uldiv(a, b, remainderp) + (cons* `(,(string-append "push___0")) + `(,(string-append "push___%" r1)) + `(,(string-append "push___%" r0)) + (armv4:call-label #f "__mesabi_uldiv" 3))))) + +(define (armv4:r0%r1 info signed?) + (let ((r0 (get-r0 info)) + (r1 (get-r1 info))) + (if signed? + ;; __mesabi_imod(a,b) + (cons* `(,(string-append "push___%" r1)) + `(,(string-append "push___%" r0)) + (armv4:call-label #f "__mesabi_imod" 2)) + ;; __mesabi_uldiv(a, b, remainderp) + (append `(("push___%r0") ; slot for remainder + ("mov____%esp,%r0") + ("push___%r0") ; pointer to remainder + (,(string-append "push___%" r1)) + (,(string-append "push___%" r0))) + (armv4:call-label #f "__mesabi_uldiv" 3) + `(("pop____%r0")))))) + +(define (armv4:r+value info v) + (let ((r (get-r info))) + (if (< (abs v) #x100) + (if (< v 0) + `(((#:immediate1 ,(abs v)) ,(string-append "sub____$i8,%" r))) + `(((#:immediate1 ,v) ,(string-append "add____$i8,%" r)))) + `((,(string-append "add____$i32,%" r) (#:immediate ,v)))))) + +(define (armv4:r0->r1-mem info) + (let ((r0 (get-r0 info)) + (r1 (get-r1 info))) + `((,(string-append "mov____%" r0 ",(%" r1 ")"))))) + +(define (armv4:byte-r0->r1-mem info) + (let* ((r0 (get-r0 info)) + (r1 (get-r1 info))) + `((,(string-append "strb___%" r0 ",(%" r1 ")"))))) + +(define (armv4:word-r0->r1-mem info) + (let* ((r0 (get-r0 info)) + (r1 (get-r1 info))) + `((,(string-append "strh___%" r0 ",(%" r1 ")"))))) + +(define (armv4:r-cmp-value info v) + (let ((r (get-r info))) + (if (< (abs v) #x100) + (if (< v 0) + `(((#:immediate1 ,(abs v)) ,(string-append "cmn____$i8,%" r))) + `(((#:immediate1 ,v) ,(string-append "cmp____$i8,%" r)))) + `((,(string-append "cmp____$i32,%" r) (#:immediate ,v)))))) + +(define (armv4:push-register info r) + `((,(string-append "push___%" r)))) + +(define (armv4:pop-register info r) + `((,(string-append "pop____%" r)))) + +(define (armv4:return->r info) + (let ((r (get-r info))) + (if (equal? r "r0") '() + `((,(string-append "mov____%r0,%" r)))))) + +(define (armv4:r0-or-r1 info) + (let ((r0 (get-r0 info)) + (r1 (get-r1 info))) + `((,(string-append "or_____%" r1 ",%" r0))))) + +(define (armv4:shl-r info n) + (let ((r (get-r info))) + `(((#:immediate1 ,n) ,(string-append "lsl____%" r ",%" r ",$i8"))))) + +(define (armv4:r+r info) + (let ((r (get-r info))) + `((,(string-append "add____%" r ",%" r))))) + +(define (armv4:not-r info) + (let ((r (get-r info))) + `((,(string-append "not____%" r))))) + +(define (armv4:r0-xor-r1 info) + (let ((r0 (get-r0 info)) + (r1 (get-r1 info))) + `((,(string-append "xor____%" r1 ",%" r0))))) + +(define (armv4:r0-mem->r1-mem info) + (let* ((registers (.registers info)) + (r0 (get-r0 info)) + (r1 (get-r1 info)) + (r2 (car registers))) + `((,(string-append "mov____(%" r0 "),%" r2)) + (,(string-append "mov____%" r2 ",(%" r1 ")"))))) + +(define (armv4:byte-r0-mem->r1-mem info) + (let* ((registers (.registers info)) + (r0 (get-r0 info)) + (r1 (get-r1 info)) + (r2 (car registers))) + `((,(string-append "ldrsb_%" r2 ",(%" r0 ")")) + (,(string-append "strb___%" r2 ",(%" r1 ")"))))) + +(define (armv4:word-r0-mem->r1-mem info) + (let* ((registers (.registers info)) + (r0 (get-r0 info)) + (r1 (get-r1 info)) + (r2 (car registers))) + `((,(string-append "mov____(%" r0 "),%" r2)) + (,(string-append "strh__%" r2 ",(%" r1 ")"))))) + +(define (armv4:r0+value info v) + (let ((r0 (get-r0 info))) + (if (< (abs v) #x100) + (if (< v 0) + `(((#:immediate1 ,(abs v)) ,(string-append "sub____$i8,%" r0))) + `(((#:immediate1 ,v) ,(string-append "add____$i8,%" r0)))) + `((,(string-append "add____$i32,%" r0) (#:immediate ,v)))))) + +(define (armv4:value->r0 info v) + (let ((r0 (get-r0 info))) + `((,(string-append "mov____$i32,%" r0) (#:immediate ,v))))) + +(define (armv4:byte-r->local+n info id n) + (let* ((n (+ (- 0 (* 4 id)) n)) + (r (get-r info))) + `(,(if (< (abs n) #x100) + (if (< n 0) + `((#:immediate1 ,(abs n)) + ,(string-append "strb___%" r ",(%fp,-#$i8)")) + `((#:immediate1 ,n) + ,(string-append "strb___%" r ",(%fp,+#$i8)"))) + `(,(string-append "strb___%" r ",0x32(%ebp)") (#:immediate ,n)))))) + +(define (armv4:word-r->local+n info id n) + (let* ((n (+ (- 0 (* 4 id)) n)) + (r (get-r info))) + `(,(if (< (abs n) #x100) + (if (< n 0) + `((#:immediate1 ,(abs n)) + ,(string-append "strh___%" r ",(%fp,-#$i8)")) + `((#:immediate1 ,n) + ,(string-append "strh___%" r ",(%fp,+#$i8)"))) + `(,(string-append "strh___%" r ",0x32(%ebp)") (#:immediate ,n)))))) + +(define (armv4:r-and info v) + (let ((r (get-r info))) + `(((#:immediate1 ,v) ,(string-append "and____$i8,%" r))))) + +(define (armv4:push-r0 info) + (let ((r0 (get-r0 info))) + `((,(string-append "push___%" r0))))) + +(define (armv4:r1->r0 info) + (let ((r0 (get-r0 info)) + (r1 (get-r1 info))) + `((,(string-append "mov____%" r1 ",%" r0))))) + +(define (armv4:pop-r0 info) + (let ((r0 (get-r0 info))) + `((,(string-append "pop____%" r0))))) + +(define (armv4:swap-r-stack info) + (let ((r (get-r info))) + `((,(string-append "xchg___%" r ",(%esp)"))))) + +(define (armv4:swap-r1-stack info) + (let ((r0 (get-r0 info))) + `((,(string-append "xchg___%" r0 ",(%esp)"))))) + +(define (armv4:r2->r0 info) + (let ((r0 (get-r0 info)) + (r1 (get-r1 info)) + (allocated (.allocated info))) + (if (> (length allocated) 2) + (let ((r2 (cadddr allocated))) + `((,(string-append "mov____%" r2 ",%" r1)))) + `((,(string-append "pop____%" r0)) + (,(string-append "push___%" r0)))))) + +(define armv4:instructions + `( + (a?->r . ,armv4:a?->r) + (ae?->r . ,armv4:ae?->r) + (b?->r . ,armv4:b?->r) + (be?->r . ,armv4:be?->r) + (byte-mem->r . ,armv4:byte-mem->r) + (byte-r . ,armv4:byte-r) + (byte-r->local+n . ,armv4:byte-r->local+n) + (byte-r0->r1-mem . ,armv4:byte-r0->r1-mem) + (byte-r0->r1-mem . ,armv4:byte-r0->r1-mem) + (byte-r0-mem->r1-mem . ,armv4:byte-r0-mem->r1-mem) + (byte-signed-r . ,armv4:byte-signed-r) + (call-label . ,armv4:call-label) + (call-r . ,armv4:call-r) + (function-locals . ,armv4:function-locals) + (function-preamble . ,armv4:function-preamble) + (g?->r . ,armv4:g?->r) + (ge?->r . ,armv4:ge?->r) + (jump . ,armv4:jump) + (jump-a . ,armv4:jump-a) + (jump-ae . ,armv4:jump-ae) + (jump-b . ,armv4:jump-b) + (jump-be . ,armv4:jump-be) + (jump-byte-z . ,armv4:jump-byte-z) + (jump-g . , armv4:jump-g) + (jump-ge . , armv4:jump-ge) + (jump-l . ,armv4:jump-l) + (jump-le . ,armv4:jump-le) + (jump-nz . ,armv4:jump-nz) + (jump-z . ,armv4:jump-z) + (l?->r . ,armv4:l?->r) + (label->arg . ,armv4:label->arg) + (label->r . ,armv4:label->r) + (label-mem->r . ,armv4:label-mem->r) + (label-mem-add . ,armv4:label-mem-add) + (le?->r . ,armv4:le?->r) + (local->r . ,armv4:local->r) + (local-add . ,armv4:local-add) + (local-ptr->r . ,armv4:local-ptr->r) + (long-r0->r1-mem . ,armv4:r0->r1-mem) + (long-r0-mem->r1-mem . ,armv4:r0-mem->r1-mem) + (mem->r . ,armv4:mem->r) + (nop . ,armv4:nop) + (not-r . ,armv4:not-r) + (pop-r0 . ,armv4:pop-r0) + (pop-register . ,armv4:pop-register) + (push-r0 . ,armv4:push-r0) + (push-register . ,armv4:push-register) + (r+r . ,armv4:r+r) + (r+value . ,armv4:r+value) + (r->arg . ,armv4:r->arg) + (r->byte-label . ,armv4:r->byte-label) + (r->label . ,armv4:r->label) + (r->local . ,armv4:r->local) + (r->local+n . ,armv4:r->local+n) + (r->word-label . ,armv4:r->word-label) + (r-and . ,armv4:r-and) + (r-byte-mem-add . ,armv4:r-byte-mem-add) + (r-cmp-value . ,armv4:r-cmp-value) + (r-mem-add . ,armv4:r-mem-add) + (r-negate . ,armv4:r-negate) + (r-word-mem-add . ,armv4:r-word-mem-add) + (r-zero? . ,armv4:r-zero?) + (r0%r1 . ,armv4:r0%r1) + (r0*r1 . ,armv4:r0*r1) + (r0+r1 . ,armv4:r0+r1) + (r0+value . ,armv4:r0+value) + (r0->r1 . ,armv4:r0->r1) + (r0->r1-mem . ,armv4:r0->r1-mem) + (r0-and-r1 . ,armv4:r0-and-r1) + (r0-mem->r1-mem . ,armv4:r0-mem->r1-mem) + (r0-or-r1 . ,armv4:r0-or-r1) + (r0-r1 . ,armv4:r0-r1) + (r0-xor-r1 . ,armv4:r0-xor-r1) + (r0/r1 . ,armv4:r0/r1) + (r0<>r1 . ,armv4:r0>>r1) + (r1->r0 . ,armv4:r1->r0) + (r2->r0 . ,armv4:r2->r0) + (ret . ,armv4:ret) + (return->r . ,armv4:return->r) + (shl-r . ,armv4:shl-r) + (swap-r-stack . ,armv4:swap-r-stack) + (swap-r0-r1 . ,armv4:swap-r0-r1) + (swap-r1-stack . ,armv4:swap-r1-stack) + (test-r . ,armv4:test-r) + (value->r . ,armv4:value->r) + (value->r0 . ,armv4:value->r0) + (word-mem->r . ,armv4:word-mem->r) + (word-r . ,armv4:word-r) + (word-r->local+n . ,armv4:word-r->local+n) + (word-r0->r1-mem . ,armv4:word-r0->r1-mem) + (word-r0-mem->r1-mem . ,armv4:word-r0-mem->r1-mem) + (word-signed-r . ,armv4:word-signed-r) + (xor-zf . ,armv4:xor-zf) + (zf->r . ,armv4:zf->r) + )) diff --git a/module/mescc/armv4/info.scm b/module/mescc/armv4/info.scm new file mode 100644 index 00000000..b53c2bb3 --- /dev/null +++ b/module/mescc/armv4/info.scm @@ -0,0 +1,62 @@ +;;; GNU Mes --- Maxwell Equations of Software +;;; Copyright © 2018 Jan (janneke) Nieuwenhuizen +;;; Copyright © 2019 Danny Milosavljevic +;;; +;;; This file is part of GNU Mes. +;;; +;;; GNU Mes is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Mes is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Mes. If not, see . + +;;; Commentary: + +;;; Initialize MesCC as arm compiler + +;;; Code: + +(define-module (mescc armv4 info) + #:use-module (mescc info) + #:use-module (mescc armv4 as) + #:export (armv4-info)) + +(define (armv4-info) + (make #:types armv4:type-alist #:registers armv4:registers #:instructions armv4:instructions)) + +(define armv4:registers '("r0" "r1" "r2" "r3" "r4" "r5")) +(define armv4:type-alist + `(("char" . ,(make-type 'signed 1 #f)) + ("short" . ,(make-type 'signed 2 #f)) + ("int" . ,(make-type 'signed 4 #f)) + ("long" . ,(make-type 'signed 4 #f)) + ("default" . ,(make-type 'signed 4 #f)) + ("*" . ,(make-type 'unsigned 4 #f)) + ("long long" . ,(make-type 'signed 8 #f)) + ("long long int" . ,(make-type 'signed 8 #f)) + + ("void" . ,(make-type 'void 1 #f)) + ("unsigned char" . ,(make-type 'unsigned 1 #f)) + ("unsigned short" . ,(make-type 'unsigned 2 #f)) + ("unsigned" . ,(make-type 'unsigned 4 #f)) + ("unsigned int" . ,(make-type 'unsigned 4 #f)) + ("unsigned long" . ,(make-type 'unsigned 4 #f)) + + ("unsigned long long" . ,(make-type 'unsigned 8 #f)) + ("unsigned long long int" . ,(make-type 'unsigned 8 #f)) + + ("float" . ,(make-type 'float 4 #f)) + ("double" . ,(make-type 'float 4 #f)) ; FIXME + ("long double" . ,(make-type 'float 4 #f)) ; FIXME + + ("short int" . ,(make-type 'signed 2 #f)) + ("unsigned short int" . ,(make-type 'unsigned 2 #f)) + ("long int" . ,(make-type 'signed 4 #f)) + ("unsigned long int" . ,(make-type 'unsigned 4 #f)))) diff --git a/module/mescc/mescc.scm b/module/mescc/mescc.scm index d54d620d..93997fe2 100644 --- a/module/mescc/mescc.scm +++ b/module/mescc/mescc.scm @@ -23,6 +23,7 @@ #:use-module (ice-9 getopt-long) #:use-module (mes misc) + #:use-module (mescc armv4 info) #:use-module (mescc i386 info) #:use-module (mescc x86_64 info) #:use-module (mescc preprocess)