bug-mes
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v2] Add ARM backend.


From: Danny Milosavljevic
Subject: [PATCH v2] Add ARM backend.
Date: Sat, 6 Jun 2020 20:01:34 +0200

* 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/M1.scm (info->M1): Support ARM symbolic instructions,
including little endian instructions.  Align functions.
(hex2:offset2): New procedure.
(hex2:branch-offset3): New procedure.
---
 build-aux/build-guile.sh    |   2 +
 lib/arm-mes/arm.M1          | 401 +++++++++++++++++++++++
 module/mescc/M1.scm         |  14 +-
 module/mescc/armv4/as.scm   | 628 ++++++++++++++++++++++++++++++++++++
 module/mescc/armv4/info.scm |  62 ++++
 5 files changed, 1106 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..7efb4a57
--- /dev/null
+++ b/lib/arm-mes/arm.M1
@@ -0,0 +1,401 @@
+### GNU Mes --- Maxwell Equations of Software
+### Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
+### Copyright © 2019 Danny Milosavljevic <dannym@scratchpost.org>
+###
+### 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 <http://www.gnu.org/licenses/>.
+
+# 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, div)
+
+DEFINE R0 0
+DEFINE R1 1
+DEFINE R2 2
+DEFINE R3 3
+DEFINE R7 7
+DEFINE R14 E
+DEFINE PC F
+
+# The E 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 # mov     r1, #66
+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
+
+# fp -> r0
+DEFINE mov____%r11,%r0 0b00a0e1
+
+# e59f9004        ldr     r9, [pc, #4]    ; <L1>
+# e5890000        str     r0, [r9]
+# ea000000        b L2
+# L1: ???
+# L2:
+DEFINE mov____%r0,0x32 04909fe5000089e5000000ea
+
+DEFINE mov____%r2,0x32 04909fe5002089e5000000ea
+
+# e92d0005        push    {r0, r2}
+# e5910000        ldr     r0, [r1]
+# e59f200c        ldr     r2, [pc, #12]   ; 1c <X2>
+# e0800002        add     r0, r0, r2
+# e5810000        str     r0, [r1]
+# e8bd0005        pop     {r0, r2}
+# ea000000        b       20 <Y2>
+# X2: ???
+# Y2:
+DEFINE add____$i32,(%r1) 
05002de9000091e50c209fe5020080e0000081e50500bde8000000ea
+
+# e59f0000        ldr     r0, [pc]
+# ea000000        b       c <R>
+# 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 <L1x>
+# e52d9004        push    {r9}            ; (str r9, [sp, #-4]!)
+# ea000000        b       10 <L1y>
+# 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 <LX1>
+# e089900b        add     r9, r9, fp
+# e5890000        str     r0, [r9]
+# ea000000        b       14 <LX2>
+# 00000010 <LX1>: data
+# 00000014 <LX2>:
+DEFINE mov____%r0,0x32(%ebp) 08909fe50b9089e0000089e5000000ea
+DEFINE mov____%r1,0x32(%ebp) 08909fe50b9089e0001089e5000000ea
+DEFINE mov____%r2,0x32(%ebp) 08909fe50b9089e0002089e5000000ea
+
+# e59f9004        ldr     r9, [pc, #4]    ; c <LX1>
+# e5990000        ldr     r0, [r9]
+# ea000000        b       10 <LX2>
+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
+
+# e59f9008        ldr     r9, [pc, #8]
+# e089900b        add     r9, r9, fp
+# e5991000        ldr     r1, [r9]
+# ea000000        b       20 <VD>
+# V: ...
+# VD:
+DEFINE mov____0x32(%ebp),%r1 08909fe50b9089e0001099e5000000ea
+DEFINE mov____0x32(%ebp),%r0 08909fe50b9089e0000099e5000000ea
+
+# 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 <WERT>
+# e5909000        ldr     r9, [r0]
+# e0999001        adds    r9, r9, r1
+# e5809000        str     r9, [r0]
+# e49d1004        pop     {r1}            ; (ldr r1, [sp], #4)
+# ea000000        b       20 <VD>
+# V: ...
+# VD:
+DEFINE add____$i32,(%r0) 
04102de510109fe5009090e5019099e0009080e504109de4000000ea
+
+# mov %r9, #00
+# push {%r9}
+DEFINE push___0 0090a0e304902de5
+
+# e59f9004        ldr     r9, [pc, #4]    ; c <VALUE>
+# e0911009        adds    r1, r1, r9
+# ea000000        b       10
+# VALUE:
+DEFINE add____$i32,%r1 04909fe5091091e0000000ea
+DEFINE add____$i32,%r0 04909fe5090090e0000000ea
+DEFINE add____$i32,%r2 04909fe5092092e0000000ea
+
+# e59f9008        ldr     r9, [pc, #8]    ; 10 <WERT>
+# e089900b        add     r9, r9, fp
+# e5c90000        strb    r0, [r9]
+# ea000000        b       14 <WERTD>
+# 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..2c9a477e 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:branch-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))
+          ((#:branch-offset3 ,offset3) (hex2:branch-offset3 offset3))
           ((#:immediate ,immediate) (hex2:immediate immediate))
           ((#:immediate1 ,immediate1) (hex2:immediate1 immediate1))
           ((#:immediate2 ,immediate2) (hex2:immediate2 immediate2))
@@ -191,11 +200,14 @@
                 ((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"))
+        (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..5a6369cd
--- /dev/null
+++ b/module/mescc/armv4/as.scm
@@ -0,0 +1,628 @@
+;;; GNU Mes --- Maxwell Equations of Software
+;;; Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
+;;; Copyright © 2019 Danny Milosavljevic <dannym@scratchpost.org>
+;;;
+;;; 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 <http://www.gnu.org/licenses/>.
+
+;;; 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)
+  `(((#:branch-offset3 ,label) bl)
+    ; FIXME: Can n be negative?
+    ((#: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)
+  `(((#:branch-offset3 ,label) "b")))
+
+(define (armv4:jump-z info label)
+  `(((#:branch-offset3 ,label) "je")))
+
+(define (armv4:jump-nz info label)
+  `(((#:branch-offset3 ,label) "jne")))
+
+(define (armv4:jump-byte-z info label)
+  `(("test___%r0,%r0") ; TODO: 1 Byte ?
+    ((#:branch-offset3 ,label) "je")))
+
+;; signed
+(define (armv4:jump-g info label)
+  `(((#:branch-offset3 ,label) "jg")))
+
+(define (armv4:jump-ge info label)
+  `(((#:branch-offset3 ,label) "jge")))
+
+(define (armv4:jump-l info label)
+  `(((#:branch-offset3 ,label) "jl" )))
+
+(define (armv4:jump-le info label)
+  `(((#:branch-offset3 ,label) "jle")))
+
+;; unsigned
+(define (armv4:jump-a info label)
+  `(((#:branch-offset3 ,label) "ja")))
+
+(define (armv4:jump-ae info label)
+  `(((#:branch-offset3 ,label) "jae")))
+
+(define (armv4:jump-b info label)
+  `(((#:branch-offset3 ,label) "jb")))
+
+(define (armv4:jump-be info label)
+  `(((#:branch-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 "lsl____%" r0 ",%" r0 ",%" r1)))))
+
+;; FIXME: lsr??! Signed or unsigned r0?
+(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)))))
+
+;; FIXME: Signed or not?
+(define (armv4:r0/r1 info signed?)
+  (let ((r0 (get-r0 info))
+        (r1 (get-r1 info)))
+    ;; __mesabi_uldiv(a, b, remainderp)
+    (cons* `(,(string-append "push___0"))
+           `(,(string-append "push___%" r1))
+           `(,(string-append "push___%" r0))
+           (armv4:call-label #f "__mesabi_uldiv" (* 4 3)))))
+
+(define (armv4:r0%r1 info signed?)
+  (let ((r0 (get-r0 info))
+        (r1 (get-r1 info)))
+    ;; __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" (* 4 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)
+    (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 <janneke@gnu.org>
+;;; Copyright © 2019 Danny Milosavljevic <dannym@scratchpost.org>
+;;;
+;;; 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 <http://www.gnu.org/licenses/>.
+
+;;; 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 <info> #: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))))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]