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.
This commit is contained in:
parent
70e7232831
commit
040220acee
|
@ -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
|
||||
|
|
390
lib/arm-mes/arm.M1
Normal file
390
lib/arm-mes/arm.M1
Normal file
|
@ -0,0 +1,390 @@
|
|||
### GNU Mes --- Maxwell Equations of Software
|
||||
### Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
|
||||
### Copyright © 2019,2020 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)
|
||||
|
||||
# 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] ; <L1>
|
||||
# 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 <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
|
||||
|
||||
DEFINE mov____0x32(%ebp),%r0 08909fe50b9089e0000099e5000000ea
|
||||
# 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
|
||||
|
||||
# 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
|
||||
|
||||
DEFINE add____$i32,%r0 04909fe5090090e0000000ea
|
||||
# e59f9004 ldr r9, [pc, #4] ; c <VALUE>
|
||||
# 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 <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
|
|
@ -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)
|
||||
|
|
636
module/mescc/armv4/as.scm
Normal file
636
module/mescc/armv4/as.scm
Normal file
|
@ -0,0 +1,636 @@
|
|||
;;; 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)
|
||||
`(((#: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 "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)))))
|
||||
|
||||
(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)
|
||||
(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)
|
||||
))
|
62
module/mescc/armv4/info.scm
Normal file
62
module/mescc/armv4/info.scm
Normal file
|
@ -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))))
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue