Add initial ARM implementation.
* include/linux/arm/syscall.h: New file. * lib/arm-mes/arm.M1: New file. * lib/arm-mes/elf-0footer.hex2: New file. * lib/arm-mes/elf32-0header.hex2: New file. * lib/arm-mes/elf32-body-exit-42.hex2: New file. * lib/arm-mes/elf32-footer-single-main.hex2: New file. * lib/arm-mes/elf32-header.hex2: New file. * lib/arm-mes-mescc/exit-42.c: New file. * lib/arm-mes-mescc/setjmp.c: New file. * module/mescc/armv4/as.scm: New file. * module/mescc/armv4/info.scm: New file. * module/mescc/M1.scm (hex2:offset2): New procedure. * module/mescc/mescc.scm: Include (mescc armv4 info). (hex2:offset3): New procedure. (info->M1): Use them. * build-aux/build-guile.sh: Compile them.
This commit is contained in:
parent
314e25e532
commit
83d8e41020
|
@ -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
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/* -*-comment-start: "//";comment-end:""-*-
|
||||
* 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/>.
|
||||
*/
|
||||
#ifndef __MES_LINUX_ARM_SYSCALL_H
|
||||
#define __MES_LINUX_ARM_SYSCALL_H 1
|
||||
|
||||
// libc
|
||||
#define SYS_fork 0x900002
|
||||
#define SYS_read 0x900003
|
||||
#define SYS_open 0x900005
|
||||
//#define SYS_waitpid
|
||||
#define SYS_wait4 0x900072
|
||||
#define SYS_execve 0x90000b
|
||||
#define SYS_chmod 0x90000f
|
||||
#define SYS_access 0x900021
|
||||
#define SYS_brk 0x90002d
|
||||
#define SYS_ioctl 0x900036
|
||||
#define SYS_fsync 0x900076
|
||||
|
||||
// libc+tcc
|
||||
#define SYS_close 0x900006
|
||||
#define SYS_time 0x90000d
|
||||
#define SYS_lseek 0x900013
|
||||
#define SYS_unlink 0x90000a
|
||||
#define SYS_rmdir 0x900028
|
||||
#define SYS_gettimeofday 0x90004e
|
||||
#define SYS_stat 0x90006a
|
||||
#define SYS_getcwd 0x9000b7
|
||||
|
||||
// libc+gnu
|
||||
#define SYS_chdir 0x90000c
|
||||
#define SYS_link 0x900009
|
||||
#define SYS_getpid 0x900014
|
||||
#define SYS_getuid 0x900018
|
||||
#define SYS_kill 0x900025
|
||||
#define SYS_rename 0x900026
|
||||
#define SYS_mkdir 0x900027
|
||||
#define SYS_dup 0x900029
|
||||
#define SYS_pipe 0x90002a
|
||||
#define SYS_getgid 0x90002f
|
||||
#define SYS_rt_sigaction 0x9000ae
|
||||
#define SYS_rt_sigreturn 0x9000ad
|
||||
#define SYS_fcntl 0x900037
|
||||
#define SYS_dup2 0x90003f
|
||||
#define SYS_getrusage 0x90004d
|
||||
#define SYS_lstat 0x90006b
|
||||
#define SYS_setitimer 0x900068
|
||||
#define SYS_fstat 0x90006c
|
||||
#define SYS_nanosleep 0x9000a2
|
||||
#define SYS_getdents 0x90008d
|
||||
#define SYS_clock_gettime 0x900107
|
||||
|
||||
// bash
|
||||
#define SYS_setuid 0x900017
|
||||
#define SYS_setgid 0x90002e
|
||||
#define SYS_geteuid 0x900031
|
||||
#define SYS_getegid 0x900032
|
||||
#define SYS_getppid 0x900040
|
||||
|
||||
// make+WITH_GLIBC
|
||||
#define SYS_rt_sigprocmask 0x9000af
|
||||
|
||||
// tar
|
||||
#define SYS_symlink 0x900053
|
||||
#define SYS_readlink 0x900055
|
||||
#define SYS_mknod 0x90000e
|
||||
|
||||
#endif // __MES_LINUX_ARM_SYSCALL_H
|
|
@ -0,0 +1,25 @@
|
|||
/* -*-comment-start: "//";comment-end:""-*-
|
||||
* GNU Mes --- Maxwell Equations of Software
|
||||
* Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.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/>.
|
||||
*/
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
return 42;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/* -*-comment-start: "//";comment-end:""-*-
|
||||
* GNU Mes --- Maxwell Equations of Software
|
||||
* Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.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/>.
|
||||
*/
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
void
|
||||
longjmp (jmp_buf env, int val)
|
||||
{
|
||||
val = val == 0 ? 1 : val;
|
||||
///asm ("!0x0c mov____0x8(%ebp),%eax"); // val
|
||||
asm ("!0x08 mov____0x8(%ebp),%ebp"); // env*
|
||||
|
||||
asm ("!0x4 mov____0x8(%ebp),%ebx"); // env.__pc
|
||||
asm ("!0x8 mov____0x8(%ebp),%esp"); // env.__sp
|
||||
asm ("!0x0 mov____0x8(%ebp),%ebp"); // env.__bp
|
||||
asm ("jmp____*%r1");
|
||||
// not reached
|
||||
exit (42);
|
||||
}
|
||||
|
||||
int
|
||||
setjmp (__jmp_buf *env)
|
||||
{
|
||||
long *p = (long*)&env;
|
||||
env[0].__bp = p[-2];
|
||||
env[0].__pc = p[-1];
|
||||
env[0].__sp = (long)&env;
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,306 @@
|
|||
### 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!
|
||||
|
||||
# FIXME: https://w3challs.com/syscalls/?arch=arm_strong
|
||||
|
||||
# reduced instruction set: r0, r1 (some r2 for shift, r3 for mul, div)
|
||||
# FIXME: count instructions
|
||||
|
||||
#DEFINE add____$i32,(%r0) xx
|
||||
#DEFINE add____$i32,(%r1) xx
|
||||
#DEFINE add____$i32,0x32(%r0) xx
|
||||
DEFINE add____$i8,%r0 0090e2 # adds r0, r0, #xx
|
||||
DEFINE add____$i8,%r1 1091e2 # adds r1, r1, #xx
|
||||
DEFINE add____$i8,%r13 d09de2 # adds r13, r13, #xx
|
||||
#DEFINE add____$i8,(%r0) xx
|
||||
#DEFINE add____$i8,(%r1) xx
|
||||
#DEFINE add____$i8,0x32 xx
|
||||
#DEFINE add____$i8,0x32(%r0) xx
|
||||
#DEFINE add____$i8,0x8(%r0) xx
|
||||
DEFINE add____%r0,%r0 000090e0 # adds r0, r0, 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 call32 xx
|
||||
#DEFINE call___*%r0 xx
|
||||
#DEFINE call___*%r1 xx
|
||||
#DEFINE cltd xx
|
||||
#DEFINE cmp____$0x32,%r0 xx
|
||||
#DEFINE cmp____$i32,%r0 xx
|
||||
DEFINE cmp____$i8,%r0 0050e3
|
||||
DEFINE cmp____$i8,%r1 0051e3
|
||||
#DEFINE div___%r1 xx
|
||||
DEFINE hlt 700000e1
|
||||
#DEFINE idiv___%r1 xx
|
||||
#DEFINE int xx
|
||||
DEFINE swi____$0 000000ef
|
||||
DEFINE ja 8a
|
||||
DEFINE jae 3a
|
||||
DEFINE jb 2a
|
||||
DEFINE jbe 9a
|
||||
DEFINE je 0a
|
||||
DEFINE je 0a
|
||||
DEFINE jg ca
|
||||
DEFINE jge aa
|
||||
DEFINE jl ba
|
||||
DEFINE jle da
|
||||
#DEFINE jmp____*%r1 xx
|
||||
DEFINE jne 1a
|
||||
#DEFINE lea____0x32(%ebp),%r0 xx
|
||||
#DEFINE lea____0x8(%ebp),%r0 xx
|
||||
|
||||
# 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 mov____%r0,%r1 0010a0e1
|
||||
DEFINE mov____%r0,%r2 0020a0e1
|
||||
DEFINE mov____%r0,(%r1) 000081e5
|
||||
DEFINE mov____%r1,%r0 0100a0e1
|
||||
DEFINE mov____%r1,%r2 0120a0e1
|
||||
#DEFINE mov____%r1,0x32 xx
|
||||
|
||||
# fp -> r0
|
||||
DEFINE mov____%r11,%r0 0b00a0e1
|
||||
|
||||
# e52d1004 push {r1} ; (str r1, [sp, #-4]!)
|
||||
# e59f1004 ldr r1, [pc, #4] ; 10 <L1>
|
||||
# e5810000 str r0, [r1]
|
||||
# e49d1004 pop {r1} ; (ldr r1, [sp], #4)
|
||||
# ea000000 b L2
|
||||
# L1: ???
|
||||
# L2:
|
||||
DEFINE mov____%r0,0x32 04102de504109fe5000081e504109de4000000ea
|
||||
|
||||
# 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
|
||||
|
||||
# e52d0004 push {r0} ; (str r0, [sp, #-4]!)
|
||||
# e59f0008 ldr r0, [pc, #8] ; 14 <addr1>
|
||||
# e5901000 ldr r1, [r0]
|
||||
# e49d0004 pop {r0} ; (ldr r0, [sp], #4)
|
||||
# ea000000 b 18 <addr2>
|
||||
# addr1: ???
|
||||
# addr2:
|
||||
DEFINE mov____0x32,%r1 04002de508009fe5001090e504009de4000000ea
|
||||
|
||||
#DEFINE mov____%r1,0x32(%ebp) xx
|
||||
#DEFINE mov____%r1,0x8(%ebp) xx
|
||||
DEFINE mov____%r2,(%r1) 002081e5
|
||||
DEFINE mov____%r3,%r0 0300a0e1
|
||||
DEFINE mov____%r3,%r1 0e10a0e1
|
||||
#DEFINE mov____%r13,%ebp xx
|
||||
DEFINE mov____(%r0),%r0 000090e5
|
||||
DEFINE mov____(%r0),%r2 002090e5
|
||||
DEFINE mov____(%r1),%r1 001091e5
|
||||
#DEFINE mul____%r1 xx
|
||||
#DEFINE mul_____%r1 xx
|
||||
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
|
||||
|
||||
# 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___%ebp xx
|
||||
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___(%r0) xx
|
||||
#DEFINE push___0x32(%ebp) xx
|
||||
#DEFINE push___0x8(%ebp) xx
|
||||
DEFINE ret 4770 #e1a0f00e
|
||||
#DEFINE shl____$i8,%r0 xx # complicated encoding
|
||||
#DEFINE shl____$i8,%r1 xx # complicated encoding
|
||||
#DEFINE sub____$8,%r13 xx
|
||||
#DEFINE sub____$i32,%r13 xx
|
||||
DEFINE sub____%r1,%r0 e0500001 # subs r0, r0, r1
|
||||
#DEFINE test___%al,%al xx
|
||||
DEFINE test___%r0,%r0 000010e1
|
||||
DEFINE test___%r1,%r1 010011e1
|
||||
#DEFINE xchg___%r0,%r1 xx
|
||||
#DEFINE xchg___%r0,(%r13) xx
|
||||
#DEFINE xchg___%r1,(%r13) xx
|
||||
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
|
||||
DEFINE mov____0x8(%ebp),%r0 08009be5 # ldr r0, [fp, #8]
|
||||
DEFINE mov____0x8(%ebp),%r1 08109be5 # ldr r1, [fp, #8]
|
||||
DEFINE mov____0x8(%ebp),%r2 08209be5 # ldr r2, [fp, #8]
|
||||
|
||||
# Note: These are the native ARM instructions.
|
||||
# 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 strb___%r0,(%r0) 0000c0e5 # strb r0, [r0]
|
||||
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 strh___%r0,(%r0) b000c0e1 # strh r0, [r0]
|
||||
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]
|
||||
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 movseq_%r0,$i8 00b003 # movseq r0, #xx
|
||||
#DEFINE movs___%r0,$i8 00b0e3 # movs r0, #xx
|
||||
#DEFINE teq____%r0,%r0 000030e1 # teq r0, r0
|
||||
#DEFINE teq____%r1,$i8 420031e3 # teq r1, #xx
|
||||
DEFINE asr____%r0,%r0,%r1 5001a0e1 # asr %r0, %r0, %r1
|
||||
DEFINE lsl____%r0,%r0,%r1 1001a0e1 # lsl %r0, %r0, %r1
|
||||
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
|
||||
DEFINE add____%r2,$i8 2082e2
|
||||
DEFINE bl ba
|
||||
DEFINE b ea
|
||||
DEFINE sxtb__%r0,%r0 7000afe6
|
||||
DEFINE sxth__%r0,%r0 7000bfe6
|
||||
DEFINE uxtb__%r0,%r0 7000efe6
|
||||
DEFINE uxth__%r0,%r0 7000ffe6
|
||||
|
||||
# deprecated, remove after 0.18
|
||||
#DEFINE sub____%r13,$i32 ec81
|
||||
#DEFINE sub____%r13,$i8 ec83
|
||||
|
||||
DEFINE SYS_exit 010090
|
||||
DEFINE SYS_fork 020090
|
||||
DEFINE SYS_read 030090
|
||||
DEFINE SYS_rmdir 280090
|
||||
DEFINE SYS_write 040090
|
||||
DEFINE SYS_open 050090
|
||||
DEFINE SYS_close 060090
|
||||
# DEFINE SYS_waitpid does_not_exist
|
||||
DEFINE SYS_wait4 720090
|
||||
# waitid: 900118
|
||||
#__waitpid (__pid_t pid, int *stat_loc, int options)
|
||||
# return SYSCALL_CANCEL (wait4, pid, stat_loc, options, NULL); # the NULL is more!
|
||||
|
||||
# Linux note: sys_waitpid() remains for compatibility. waitpid() should be implemented by calling sys_wait4() from libc.a.
|
||||
DEFINE SYS_unlink 0a0090
|
||||
DEFINE SYS_execve 0b0090
|
||||
DEFINE SYS_chmod 0f0090
|
||||
DEFINE SYS_lseek 130090
|
||||
DEFINE SYS_access 210090
|
||||
DEFINE SYS_brk 2d0090
|
||||
DEFINE SYS_ioctl 360090
|
||||
DEFINE SYS_stat 6a0090
|
||||
DEFINE SYS_fsync 760090
|
||||
DEFINE SYS_getcwd b70090
|
||||
|
||||
# These are x86 ABI remnants:
|
||||
|
||||
DEFINE mov____%ebp,%r0 0b00a0e1
|
||||
DEFINE mov____%ebp,%r1 0b10a0e1
|
||||
DEFINE push___%ebp 04002de5 # str r0, [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
|
||||
|
||||
# Note: i8 immediate
|
||||
DEFINE mov____%r0,0x8(%ebp) 008be5
|
||||
DEFINE mov____%r1,0x8(%ebp) 108be5
|
||||
DEFINE mov____%r2,0x8(%ebp) 208be5
|
||||
DEFINE mov____%r3,0x8(%ebp) 308be5
|
||||
DEFINE mov____%r4,0x8(%ebp) 408be5
|
||||
DEFINE mov____%r5,0x8(%ebp) 508be5
|
||||
# Note: i8 immediate
|
||||
DEFINE mov____0x8(%ebp),%r0 009be5
|
||||
DEFINE mov____0x8(%ebp),%r1 109be5
|
||||
DEFINE mov____0x8(%ebp),%r2 209be5
|
||||
DEFINE mov____0x8(%ebp),%r3 309be5
|
||||
DEFINE mov____0x8(%ebp),%r4 409be5
|
||||
DEFINE mov____0x8(%ebp),%r5 509be5
|
||||
|
||||
# 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
|
||||
|
||||
# The flags are also updated, but that's probably useless.
|
||||
DEFINE add____$i8,%esp d09de2
|
||||
#DEFINE add____$i32,0x32(%ebp) xx
|
||||
#DEFINE add____$i8,0x32(%ebp) xx
|
||||
#DEFINE add____$i8,0x8(%ebp) xx
|
||||
#DEFINE add____%ebp,%r0 xx
|
||||
|
||||
# e24ddeff sub sp, sp, #4080
|
||||
# e24dd064 sub sp, sp, #100
|
||||
DEFINE allocate_stack_4180 ffde4de264d04de2
|
|
@ -0,0 +1,27 @@
|
|||
### Copyright (C) 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
|
||||
### Copyright (C) 2019 Danny Milosavljevic <dannym@scratchpost.org>
|
||||
### This file is part of stage0.
|
||||
###
|
||||
### stage0 is free software: you an 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.
|
||||
###
|
||||
### stage0 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 stage0. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
### stage0's hex2 format for arm
|
||||
### !<label> 1 byte relative
|
||||
### $<label> 2 byte address
|
||||
### @<label> 2 byte relative
|
||||
### &<label> 4 byte address
|
||||
### %<label> 4 byte relative
|
||||
### local_<label> function-local
|
||||
### string_<index> string #<index>
|
||||
|
||||
:ELF_end
|
|
@ -0,0 +1,81 @@
|
|||
### Copyright (C) 2016 Jeremiah Orians
|
||||
### Copyright (C) 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
|
||||
### Copyright (C) 2019 Danny Milosavljevic <dannym@scratchpost.org>
|
||||
### This file is part of stage0.
|
||||
###
|
||||
### stage0 is free software: you an 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.
|
||||
###
|
||||
### stage0 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 stage0. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
### stage0's hex2 format for arm
|
||||
### !<label> 1 byte relative
|
||||
### $<label> 2 byte address
|
||||
### @<label> 2 byte relative
|
||||
### &<label> 4 byte address
|
||||
### %<label> 4 byte relative
|
||||
### local_<label> function-local
|
||||
### string_<index> string #<index>
|
||||
|
||||
### elf32-header-exit-42.hex2: 32 bit elf header in hex2 for `exit 42'
|
||||
|
||||
:ELF_base
|
||||
7F 45 4C 46 # e_ident[EI_MAG0-3] ELF's magic number
|
||||
|
||||
01 # e_ident[EI_CLASS] Indicating 32 bit
|
||||
01 # e_ident[EI_DATA] Indicating little endianness
|
||||
01 # e_ident[EI_VERSION] Indicating original elf
|
||||
|
||||
00 # e_ident[EI_OSABI] Set at 0 because none cares
|
||||
00 # e_ident[EI_ABIVERSION] See above
|
||||
|
||||
00 00 00 00 00 00 00 # e_ident[EI_PAD]
|
||||
|
||||
# Row 2 in od:
|
||||
|
||||
02 00 # e_type Indicating Executable
|
||||
28 00 # e_machine Indicating 32bit arm
|
||||
01 00 00 00 # e_version Indicating original elf
|
||||
|
||||
&ELF_text # e_entry Address of the entry point
|
||||
&ELF_program_headers>ELF_base # e_phoff Address of program header table
|
||||
00 00 00 00 # e_shoff Address of section header table
|
||||
|
||||
00 00 00 00 # e_flags
|
||||
|
||||
34 00 # e_ehsize Indicating our 52 Byte header
|
||||
|
||||
20 00 # e_phentsize size of a program header table
|
||||
01 00 # e_phnum number of entries in program table
|
||||
|
||||
00 00 # e_shentsize size of a section header table
|
||||
00 00 # e_shnum number of entries in section table
|
||||
|
||||
00 00 # e_shstrndx index of the section names
|
||||
|
||||
# @34
|
||||
00 00 00 00
|
||||
00 00 00 00
|
||||
00 00 00 00
|
||||
|
||||
# @40
|
||||
:ELF_program_headers
|
||||
:ELF_program_header__text
|
||||
01 00 00 00 # ph_type: PT-LOAD = 1
|
||||
00 00 00 00 # ph_offset
|
||||
&ELF_base # ph_vaddr
|
||||
&ELF_base # ph_physaddr
|
||||
&ELF_end>ELF_base # ph_filesz
|
||||
&ELF_end>ELF_base # ph_memsz
|
||||
07 00 00 00 # ph_flags: PF-X|PF-W|PF-R = 7
|
||||
01 00 00 00 # ph_align
|
||||
|
||||
:ELF_text
|
|
@ -0,0 +1,49 @@
|
|||
### Copyright (C) 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
|
||||
### Copyright (C) 2019 Danny Milosavljevic <dannym@scratchpost.org>
|
||||
### This file is part of stage0.
|
||||
###
|
||||
### stage0 is free software: you an 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.
|
||||
###
|
||||
### stage0 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 stage0. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
### stage0's hex2 format for arm
|
||||
### !<label> 1 byte relative
|
||||
### $<label> 2 byte address
|
||||
### @<label> 2 byte relative
|
||||
### &<label> 4 byte address
|
||||
### %<label> 4 byte relative
|
||||
### local_<label> function-local
|
||||
### string_<index> string #<index>
|
||||
|
||||
### elf32-body-exit-42.hex2: 32 bit elf body in hex2 for `exit 42'
|
||||
|
||||
# @200
|
||||
:ELF_text
|
||||
:_start
|
||||
# exit(42)
|
||||
|
||||
~main ea # b main
|
||||
00 00 00
|
||||
00 00 00 00
|
||||
00 00 00 00
|
||||
|
||||
:main
|
||||
|
||||
42 00 a0 e3 # mov $42 -> %r0
|
||||
01 70 a0 e3 # mov $0x1 -> %r7
|
||||
00 00 00 ef # swi 0
|
||||
|
||||
00 00 00 00
|
||||
|
||||
# @220
|
||||
:ELF_data
|
||||
65 78 69 74 34 32 20 64 61 74 61 20 68 65 72 65 # "exit42 data here"
|
|
@ -0,0 +1,65 @@
|
|||
### Copyright (C) 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
|
||||
### Copyright (C) 2019 Danny Milosavljevic <dannym@scratchpost.org>
|
||||
### This file is part of stage0.
|
||||
###
|
||||
### stage0 is free software: you an 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.
|
||||
###
|
||||
### stage0 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 stage0. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
### stage0's hex2 format for arm
|
||||
### !<label> 1 byte relative
|
||||
### $<label> 2 byte address
|
||||
### @<label> 2 byte relative
|
||||
### &<label> 4 byte address
|
||||
### %<label> 4 byte relative
|
||||
### local_<label> function-local
|
||||
### string_<index> string #<index>
|
||||
|
||||
### elf32-footer-single-main.hex2: 32 bit elf footer in hex2 for single main
|
||||
|
||||
# @230
|
||||
|
||||
:ELF_str
|
||||
00 # 0
|
||||
:ELF_str__start
|
||||
5f 73 74 61 72 74 00 # _start
|
||||
:ELF_str__main
|
||||
6d 61 69 6e 00 # main
|
||||
|
||||
00 00 00
|
||||
|
||||
# @240
|
||||
:ELF_sym
|
||||
00 00 00 00 # st-name
|
||||
00 00 00 00 # st-offset: &_start - BaseAddress
|
||||
00 00 00 00 # st-len : &main - _start
|
||||
00 # st-info = stt-func= 2
|
||||
00 # st-other
|
||||
01 00 # st-shndx: 1
|
||||
|
||||
# _start
|
||||
&ELF_str__start>ELF_str # st-name
|
||||
&_start
|
||||
10 00 00 00 # st-len : &main - _start
|
||||
02 # st-info = stt-func= 2
|
||||
00 # st-other
|
||||
01 00 # st-shndx: 1
|
||||
|
||||
# main
|
||||
&ELF_str__main>ELF_str # st-name
|
||||
&main
|
||||
10 00 00 00 # st-len : &ELF_data - main
|
||||
02 # st-info = stt-func= 2
|
||||
00 # st-other
|
||||
01 00 # st-shndx: 1
|
||||
|
||||
:ELF_end
|
|
@ -0,0 +1,220 @@
|
|||
### Copyright (C) 2016 Jeremiah Orians
|
||||
### Copyright (C) 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
|
||||
### Copyright (C) 2019 Danny Milosavljevic <dannym@scratchpost.org>
|
||||
### This file is part of stage0.
|
||||
###
|
||||
### stage0 is free software: you an 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.
|
||||
###
|
||||
### stage0 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 stage0. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
### stage0's hex2 format for arm
|
||||
### !<label> 1 byte relative
|
||||
### $<label> 2 byte address
|
||||
### @<label> 2 byte relative
|
||||
### &<label> 4 byte address
|
||||
### %<label> 4 byte relative
|
||||
### local_<label> function-local
|
||||
### string_<index> string #<index>
|
||||
|
||||
### elf32-header-exit-42.hex2: 32 bit elf header in hex2 for `exit 42'
|
||||
|
||||
:ELF_base
|
||||
7F 45 4C 46 # e_ident[EI_MAG0-3] ELF's magic number
|
||||
|
||||
01 # e_ident[EI_CLASS] Indicating 32 bit
|
||||
01 # e_ident[EI_DATA] Indicating little endianness
|
||||
01 # e_ident[EI_VERSION] Indicating original elf
|
||||
|
||||
00 # e_ident[EI_OSABI] Set at 0 because none cares
|
||||
00 # e_ident[EI_ABIVERSION] See above
|
||||
|
||||
00 00 00 00 00 00 00 # e_ident[EI_PAD]
|
||||
|
||||
02 00 # e_type Indicating Executable
|
||||
28 00 # e_machine Indicating 32bit arm
|
||||
01 00 00 00 # e_version Indicating original elf
|
||||
|
||||
&ELF_text # e_entry Address of the entry point
|
||||
&ELF_program_headers>ELF_base # e_phoff Address of program header table
|
||||
&ELF_section_headers>ELF_base # e_shoff Address of section header table
|
||||
|
||||
00 00 00 00 # e_flags
|
||||
|
||||
34 00 # e_ehsize Indicating our 52 Byte header
|
||||
|
||||
20 00 # e_phentsize size of a program header table
|
||||
01 00 # e_phnum number of entries in program table
|
||||
|
||||
28 00 # e_shentsize size of a section header table
|
||||
07 00 # e_shnum number of entries in section table
|
||||
|
||||
04 00 # e_shstrndx index of the section names
|
||||
|
||||
# @34
|
||||
00 00 00 00
|
||||
00 00 00 00
|
||||
00 00 00 00
|
||||
|
||||
# @40
|
||||
:ELF_program_headers
|
||||
:ELF_program_header__text
|
||||
01 00 00 00 # ph_type: PT-LOAD = 1
|
||||
00 00 00 00 # ph_offset
|
||||
&ELF_base # ph_vaddr
|
||||
&ELF_base # ph_physaddr
|
||||
&ELF_end>ELF_base # ph_filesz
|
||||
&ELF_end>ELF_base # ph_memsz
|
||||
07 00 00 00 # ph_flags: PF-X|PF-W|PF-R = 7
|
||||
01 00 00 00 # ph_align
|
||||
|
||||
# @60
|
||||
#:ELF_program_header__data # NOT USED
|
||||
# FIXME: linux 4.17 does not allow this overlap
|
||||
# Uhuuh, elf segment at 0000000001000000
|
||||
# requested but the memory is mapped already
|
||||
01 00 00 00 # ph_type: PT-LOAD = 1
|
||||
00 00 00 00 # ph_offset
|
||||
&ELF_base # ph_vaddr
|
||||
&ELF_base # ph_physaddr
|
||||
&ELF_end>ELF_base # ph_filesz
|
||||
&ELF_end>ELF_base # ph_memsz
|
||||
07 00 00 00 # ph_flags: PF-X|PF-W|PF-R = 7
|
||||
01 00 00 00 # ph_align
|
||||
|
||||
# @80
|
||||
:ELF_comment
|
||||
4d 45 53 00 # MES
|
||||
00 00 00 00 # align
|
||||
00 00 00 00
|
||||
00 00 00 00
|
||||
|
||||
4d 45 53 00 # MES
|
||||
00 00 00 00 # align
|
||||
00 00 00 00
|
||||
00 00 00 00
|
||||
|
||||
# @a0
|
||||
:ELF_shstr
|
||||
00
|
||||
:ELF_shstr__text
|
||||
2e 74 65 78 74 00 # .text
|
||||
:ELF_shstr__data
|
||||
2e 64 61 74 61 00 # .data
|
||||
:ELF_shstr__comment
|
||||
2e 63 6f 6d 6d 65 6e 74 00 # .comment
|
||||
:ELF_shstr__shstr
|
||||
2e 73 68 73 74 72 74 61 62 00 # .shstrtab
|
||||
:ELF_shstr__sym
|
||||
2e 73 79 6d 74 61 62 00 # .symtab
|
||||
:ELF_shstr__str
|
||||
2e 73 74 72 74 61 62 00 # .strtab
|
||||
|
||||
# @d0
|
||||
|
||||
:ELF_section_headers
|
||||
00 00 00 00 # sh_name
|
||||
00 00 00 00 # sh_type
|
||||
00 00 00 00 # sh_flags
|
||||
00 00 00 00 # sh_addr
|
||||
00 00 00 00 # sh_offset
|
||||
00 00 00 00 # sh_length
|
||||
00 00 00 00 # sh_link
|
||||
00 00 00 00 # sh_info
|
||||
01 00 00 00 # sh_1?
|
||||
00 00 00 00 # sh_entsize
|
||||
|
||||
## FIXME: M0 for calculations?
|
||||
:ELF_section_header_text
|
||||
&ELF_shstr__text>ELF_shstr # sh_name
|
||||
01 00 00 00 # sh_type = SHT_PROGBITS = 1
|
||||
06 00 00 00 # sh_flags = SHF-ALLOC|SHF-EXEC =2 | 4 = 6
|
||||
&ELF_text # sh_addr
|
||||
&ELF_text>ELF_base # sh_offset
|
||||
&ELF_data>ELF_text # sh_length
|
||||
00 00 00 00 # sh_link
|
||||
00 00 00 00 # sh_info
|
||||
01 00 00 00 # sh_1?
|
||||
00 00 00 00 # sh_entsize
|
||||
|
||||
:ELF_section_header_data
|
||||
&ELF_shstr__data>ELF_shstr # sh_name
|
||||
01 00 00 00 # sh_type = SHT_PROGBITS = 1
|
||||
03 00 00 00 # sh_flags = SHF-WRITE|SHF-ALLOC = 1 | 2 = 3
|
||||
&ELF_data # sh_addr
|
||||
&ELF_data>ELF_base # sh_offset
|
||||
&ELF_sym>ELF_data # sh_length
|
||||
00 00 00 00 # sh_link
|
||||
00 00 00 00 # sh_info
|
||||
01 00 00 00 # sh_1?
|
||||
00 00 00 00 # sh_entsize
|
||||
|
||||
:ELF_section_header_comment
|
||||
&ELF_shstr__comment>ELF_shstr # sh_name
|
||||
01 00 00 00 # sh_type = SHT_PROGBITS = 1
|
||||
00 00 00 00 # sh_flags
|
||||
&ELF_comment # sh_addr
|
||||
&ELF_comment>ELF_base # sh_offset
|
||||
&ELF_shstr>ELF_comment # sh_length
|
||||
00 00 00 00 # sh_link
|
||||
00 00 00 00 # sh_info
|
||||
01 00 00 00 # sh_1?
|
||||
00 00 00 00 # sh_entsize
|
||||
|
||||
:ELF_section_header_shstr
|
||||
&ELF_shstr__shstr>ELF_shstr # sh_name
|
||||
03 00 00 00 # sh_type: str-sht-strtab
|
||||
00 00 00 00 # sh_flags
|
||||
&ELF_shstr # sh_addr
|
||||
&ELF_shstr>ELF_base # sh_offset
|
||||
&ELF_section_headers>ELF_shstr # sh_length
|
||||
00 00 00 00 # sh_link
|
||||
00 00 00 00 # sh_info
|
||||
01 00 00 00 # sh_1?
|
||||
00 00 00 00 # sh_entsize
|
||||
|
||||
:ELF_section_header_sym
|
||||
&ELF_shstr__sym>ELF_shstr # sh_name
|
||||
02 00 00 00 # sh_type: str-sht-symtab
|
||||
00 00 00 00 # sh_flags
|
||||
&ELF_sym # sh_addr
|
||||
&ELF_sym>ELF_base # sh_offset
|
||||
&ELF_end>ELF_sym # sh_length
|
||||
06 00 00 00 # sh_link:6
|
||||
00 00 00 00 # sh_info
|
||||
01 00 00 00 # sh_1?
|
||||
10 00 00 00 # sh_entsize
|
||||
|
||||
:ELF_section_header_str
|
||||
&ELF_shstr__str>ELF_shstr # sh_name
|
||||
03 00 00 00 # sh_type: str-sht-strtab
|
||||
00 00 00 00 # sh_flags
|
||||
&ELF_str # sh_addr
|
||||
&ELF_str>ELF_base # sh_offset
|
||||
&ELF_sym>ELF_str # sh_length
|
||||
00 00 00 00 # sh_link
|
||||
00 00 00 00 # sh_info
|
||||
01 00 00 00 # sh_1?
|
||||
00 00 00 00 # sh_entsize
|
||||
|
||||
# @1e8
|
||||
00 00 00 00 # align
|
||||
00 00 00 00
|
||||
|
||||
# @1f0
|
||||
|
||||
00 00 00 00 # align
|
||||
00 00 00 00
|
||||
00 00 00 00
|
||||
00 00 00 00
|
||||
|
||||
# @200
|
||||
:ELF_text
|
|
@ -63,6 +63,12 @@
|
|||
(define (hex2:offset1 o)
|
||||
(string-append "!" o))
|
||||
|
||||
(define (hex2:offset2 o)
|
||||
(string-append "@" o))
|
||||
|
||||
(define (hex2:offset3 o)
|
||||
(string-append "~" o))
|
||||
|
||||
(define hex? #t)
|
||||
|
||||
(define (hex2:immediate o)
|
||||
|
@ -171,6 +177,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))
|
||||
|
|
|
@ -0,0 +1,629 @@
|
|||
;;; 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"
|
||||
'(("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 (armv4:value->r info v)
|
||||
(let ((r (get-r info)))
|
||||
`(((#:immediate1 ,v) ,(string-append "mov____$i8,%" r)))))
|
||||
|
||||
(define (armv4:ret . rest)
|
||||
'(("mov____%ebp,%esp")
|
||||
("pop____%ebp")
|
||||
("ret")))
|
||||
|
||||
(define (armv4:r-zero? info)
|
||||
(let ((r (get-r info)))
|
||||
`((,(string-append "test___%" r "," "%" r)))))
|
||||
|
||||
(define (armv4:local->r info n)
|
||||
(let ((r (get-r info))
|
||||
(n (- 0 (* 4 n))))
|
||||
`(,(if (< (abs n) #x80)
|
||||
`((#:immediate1 ,n) ,(string-append "mov____0x8(%ebp),%" r))
|
||||
`(,(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)
|
||||
`((bl (#:offset2 ,label))
|
||||
("add____$i8,%esp" (#:immediate1 ,(* n 4)))))
|
||||
|
||||
(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_$i8,%" r)))))
|
||||
|
||||
;; 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_$i8,%r0")
|
||||
("test__%r0,%r0")))
|
||||
|
||||
(define (armv4:r->local+n info id n)
|
||||
(let ((n (+ (- 0 (* 4 id)) n))
|
||||
(r (get-r info)))
|
||||
`(,(if (< (abs n) #x80)
|
||||
`((#:immediate1 ,n) ,(string-append "mov____%" r ",0x8(%ebp)"))
|
||||
`(,(string-append "mov____%" r ",0x32(%ebp)") (#:immediate ,n))))))
|
||||
|
||||
;; FIXME: Implement M1 part.
|
||||
(define (armv4:r-mem-add info v)
|
||||
(let ((r (get-r info)))
|
||||
`(,(if (< (abs v) #x80)
|
||||
`(,(string-append "add____$i32,(%" r ")") (#:immediate ,v))
|
||||
`(,(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 "ldbrs__%r0,(%" r ")"))
|
||||
((#:immediate1 ,v) ,(string-append "addb___$i8,%r0"))
|
||||
(,(string-append "stb____%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 ")"))
|
||||
;; FIXME: That's not complete.
|
||||
((#: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) #x80) `((#: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 "movzwl_(%" 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))))
|
||||
`(,(if (and (< (abs n) #x80)
|
||||
(< (abs v) #x80)) `("add____$i32,0x32(%ebp)" (#:immediate ,n) (#:immediate ,v))
|
||||
`("add____$i32,0x32(%ebp)" (#:immediate ,n) (#:immediate ,v))))))
|
||||
|
||||
(define (armv4:label-mem-add info label v)
|
||||
`(,(if (< (abs v) #x80) `("add____$i8,0x32" (#:address ,label) (#:immediate1 ,v))
|
||||
`("add____$i32,0x32" (#:address ,label) (#:immediate ,v)))))
|
||||
|
||||
(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__$i8,%" r)))))
|
||||
|
||||
(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))
|
||||
((#:immediate1 ,(* n 4)) "add____$i8,%esp"))))
|
||||
|
||||
(define (armv4:r0*r1 info)
|
||||
(let ((allocated (.allocated info))
|
||||
(r0 (get-r0 info))
|
||||
(r1 (get-r1 info)))
|
||||
(if (not (member "edx" allocated)) ; FIXME
|
||||
`(,@(if (equal? r0 "r0") '()
|
||||
`(("push___%r0")
|
||||
(,(string-append "mov____%" r0 ",%r0"))))
|
||||
(,(string-append "mul____%" r1))
|
||||
,@(if (equal? r0 "r0") '()
|
||||
`((,(string-append "mov____%r0,%" r0))
|
||||
("pop____%r0"))))
|
||||
`(("push___%r0")
|
||||
("push___%r1")
|
||||
("push___%edx")
|
||||
(,(string-append "mov____%" r1 ",%r1"))
|
||||
(,(string-append "mov____%" r0 ",%r0"))
|
||||
(,(string-append "mul____%" r1))
|
||||
("pop____%edx")
|
||||
("pop____%r1")
|
||||
(,(string-append "mov____%r0,%" r0))
|
||||
("pop____%r0")))))
|
||||
|
||||
(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 ((signed? #f) ; nobody knows, -- all advice are belong to us?
|
||||
(allocated (.allocated info))
|
||||
(r0 (get-r0 info))
|
||||
(r1 (get-r1 info)))
|
||||
(if (not (member "edx" allocated))
|
||||
`(,@(if (equal? r0 "r0") '()
|
||||
`(("push___%r0")
|
||||
(,(string-append "mov____%" r0 ",%r0"))))
|
||||
,(if signed? '("cltd") '("xor____%edx,%edx"))
|
||||
,(if signed? `(,(string-append "idiv___%" r1)) `(,(string-append "div___%" r1)))
|
||||
,@(if (equal? r0 "r0") '()
|
||||
`((,(string-append "mov____%r0,%" r0))
|
||||
("pop____%r0"))))
|
||||
`(("push___%r0")
|
||||
("push___%r1")
|
||||
("push___%edx")
|
||||
(,(string-append "mov____%" r1 ",%r1"))
|
||||
(,(string-append "mov____%" r0 ",%r0"))
|
||||
,(if signed? '("cltd") '("xor____%edx,%edx"))
|
||||
,(if signed? `(,(string-append "idiv___%r1")) `(,(string-append "div___%r1")))
|
||||
("pop____%edx")
|
||||
("pop____%r1")
|
||||
(,(string-append "mov____%r0,%" r0))
|
||||
("pop____%r0")))))
|
||||
|
||||
(define (armv4:r0%r1 info signed?)
|
||||
(let ((signed? #f) ; nobody knows, -- all advice are belong to us?
|
||||
(allocated (.allocated info))
|
||||
(r0 (get-r0 info))
|
||||
(r1 (get-r1 info)))
|
||||
(if (not (member "edx" allocated))
|
||||
`(,@(if (equal? r0 "r0") '()
|
||||
`(("push___%r0")
|
||||
(,(string-append "mov____%" r0 ",%r0"))))
|
||||
,(if signed? '("cltd") '("xor____%edx,%edx"))
|
||||
,(if signed? `(,(string-append "idiv___%" r1)) `(,(string-append "div___%" r1)))
|
||||
(,(string-append "mov____%edx,%" r0)))
|
||||
`(("push___%r0")
|
||||
("push___%r1")
|
||||
("push___%edx")
|
||||
(,(string-append "mov____%" r1 ",%r1"))
|
||||
(,(string-append "mov____%" r0 ",%r0"))
|
||||
,(if signed? '("cltd") '("xor____%edx,%edx"))
|
||||
,(if signed? `(,(string-append "idiv___%r1")) `(,(string-append "div___%r1")))
|
||||
("pop____%edx")
|
||||
("pop____%r1")
|
||||
(,(string-append "mov____%edx,%" r0))
|
||||
("pop____%r0")))))
|
||||
|
||||
(define (armv4:r+value info v)
|
||||
(let ((r (get-r info)))
|
||||
`(,(if (< (abs v) #x80) `((#: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 "stb____%" r0 ",(%" r1 ")")))))
|
||||
|
||||
(define (armv4:word-r0->r1-mem info)
|
||||
(let* ((r0 (get-r0 info))
|
||||
(r1 (get-r1 info)))
|
||||
`((,(string-append "sthw___%" r0 ",(%" r1 ")")))))
|
||||
|
||||
(define (armv4:r-cmp-value info v)
|
||||
(let ((r (get-r info)))
|
||||
`(,(if (< (abs v) #x80) `((#: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 "shl____$i8,%" r)))))
|
||||
|
||||
(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) #x80) `((#: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) #x80)
|
||||
`((#:immediate1 ,n) ,(string-append "strb__%" r ",0x8(%ebp)"))
|
||||
`(,(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) #x80)
|
||||
`((#:immediate1 ,n) ,(string-append "strh__%" r ",0x8(%ebp)"))
|
||||
`(,(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)
|
||||
))
|
|
@ -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)) ; FIXME
|
||||
("*" . ,(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)) ; FIXME
|
||||
("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 8 #f))
|
||||
("long double" . ,(make-type 'float 8 #f))
|
||||
|
||||
("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 New Issue