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:
Danny Milosavljevic 2019-02-13 16:46:07 +01:00 committed by Jan Nieuwenhuizen
parent 314e25e532
commit 83d8e41020
No known key found for this signature in database
GPG Key ID: F3C1A0D9C1D65273
14 changed files with 1606 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

306
lib/arm-mes/arm.M1 Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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))

629
module/mescc/armv4/as.scm Normal file
View File

@ -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)
))

View 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)) ; 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))))

View File

@ -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)