Author: wmb Date: Sat Jan 1 10:56:55 2011 New Revision: 2097 URL: http://tracker.coreboot.org/trac/openfirmware/changeset/2097
Log: Added ARM simulator - thanks to Mike Tuciarone! - so cross-compiling an ARM OFW can be done without QEMU, and 5x faster than with QEMU.
Added: cpu/arm/armsim.c cpu/x86/Darwin/Makefile.armforth cpu/x86/Linux/Makefile.armsim Modified: cpu/arm/assem.fth cpu/arm/build/Makefile cpu/arm/build/builder.dic cpu/arm/disassem.fth cpu/arm/sys.fth cpu/x86/Darwin/Makefile forth/wrapper/wrapper.c forth/wrapper/zip/inflate.c
Added: cpu/arm/armsim.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ cpu/arm/armsim.c Sat Jan 1 10:56:55 2011 (r2097) @@ -0,0 +1,1199 @@ +// +// ARM32 Application-level simulator. +// +// +// Copyright (c) 2007 FirmWorks +// Copyright 2010 Apple, Inc. All rights reserved. +// See license at end. + +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> + +typedef char s8; +typedef short s16; +typedef int s32; +typedef long long s64; +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef unsigned long long u64; + +static u32 trace = 0; + +//#if TRACE +#define INSTR(a) if (trace) printf("%s -- %0x N%d Z%d C%d V%d %s\n", \ + a, COND, N, Z, C, V, cond ? "true" : "false"); \ + if (cond == 0) break +//#else +//#define INSTR(a) if (cond == 0) break +//#endif + +#define MAXMEM 0x80000 +#define MEM(type, adr) *(type *)(&mem[(adr)]) + +u32 r[16]; +#define SP r[13] +#define LR r[14] +#define PC r[15] + +void regdump(u32 instruction, u32 last_pc, u8 cr) +{ + printf(" 0 %08x 1 %08x 2 %08x 3 %08x\n", r[0], r[1], r[2], r[3]); + printf(" 4 %08x 5 %08x 6 %08x 7 %08x\n", r[4], r[5], r[6], r[7]); + printf(" 8 %08x 9 %08x a %08x b %08x\n", r[8], r[9], r[10], r[11]); + printf(" c %08x d %08x e %08x f %08x\n", r[12], r[13], r[14], r[15]); + printf("pc %08x lpc %08x i %08x ", PC - 8, last_pc, instruction); + if (cr) + putchar('\n'); +} + +#define UFIELD(lbit,nbits) ( (instruction << (31 - lbit)) >> (32 - nbits)) +#define SFIELD(lbit,nbits) ((long)(instruction << (31 - lbit)) >> (32 - nbits)) + +#define COND UFIELD(31, 4) +#define OP UFIELD(27, 7) +#define S UFIELD(20, 1) +#define L UFIELD(20, 1) +#define RD r[UFIELD(15, 4)] +#define RN r[UFIELD(19, 4)] +#define RM r[UFIELD( 3, 4)] +#define RS r[UFIELD(11, 4)] +#define TYPE UFIELD( 6, 2) +#define IMM5 UFIELD(11, 5) +#define OP1 UFIELD( 4, 1) +#define OP2 UFIELD( 7, 1) +#define ROT UFIELD(11, 4) +#define IMM8 UFIELD( 7, 8) +#define IMM24 UFIELD(23,24) +#define LINK UFIELD( 5, 1) +#define MSB UFIELD(20, 5) +#define LSB UFIELD(11, 5) +#define BXTYPE UFIELD( 7, 4) +#define IMM12 UFIELD(11,12) +#define IMM16 ((UFIELD(19, 4) << 12) | IMM12) +#define IMMHL ((UFIELD(11, 4) << 4) | UFIELD( 3, 4)) +#define P UFIELD(24, 1) +#define U UFIELD(23, 1) +#define W UFIELD(21, 1) + +// In BTGT we want to force a PC update. Since we don't implement Thumb +// the value "1" must always be invalid for last_pc. +struct { signed int imm24:24; } sext24; +#define BTGT { PC += sext24.imm24 = (IMM24 << 2); last_pc = 1; } + +#define ROTATE(imm, rot) (((imm) >> (rot)) | ((imm) << (32-(rot)))) +#define IMM32 ROTATE(IMM8, (ROT<<1)) + +#define SHSRC (OP1 ? RS : IMM5) +#define SHFT(res) \ +{ \ + switch (TYPE) { \ + case 0: res = RM << SHSRC; break; \ + case 1: res = RM >> SHSRC; break; \ + case 2: if (SHSRC == 0) { res = ((s32)(RM) < 0) ? -1 : 0; } else { res = (s32)(RM) >> SHSRC; } break; \ + case 3: res = ROTATE(RM, SHSRC); \ + } \ +} + +#define BF(sb, eb) ((u32)(((s32)0x80000000) >> (sb - eb))) >> (31 - sb); + +union { + u32 all; + struct { + u32 res :28; + u32 Vbit:1; + u32 Zbit:1; + u32 Cbit:1; + u32 Nbit:1; + } bits; +} APSR; + +#define N (APSR.bits.Nbit) +#define Z (APSR.bits.Zbit) +#define C (APSR.bits.Cbit) +#define V (APSR.bits.Vbit) + +// FIXME: We're skipping the V bit for now. + +/* Leave C alone. */ +#define UPCC(res) \ +{ \ + if (S) { \ + N = (res) >> 31; \ + Z = (res == 0); \ +/* FIXME - possible problem with C bit - should be set to carry output from shifter */ \ + } \ +} + +#define ADC(dest, a, b, c) \ +{ \ + temp = (a) + (b) + (c); \ + if (S) { \ + N = temp >> 31; \ + Z = temp == 0; \ + C = (temp < (a)) || ((c) && (temp == (a))); \ + V = ((((s32)(temp)^(s32)(a)) < 0) && (((s32)(a)^(s32)(b)) >= 0)); \ + } \ + dest = temp; \ +} + +#define SBB(dest, a, b, c) \ +{ \ + temp = (a) - (b) - (!(c)); \ + if (S) { \ + N = temp >> 31; \ + Z = temp == 0; \ + C = !(((a) < temp) || ((!(c)) && ((a) == temp))); \ + V = ((((s32)temp^(s32)(a)) < 0) && (((s32)(a)^(s32)(b)) < 0)); \ + } \ + dest = temp; \ +} + +#define UNIMP(s) \ +{ \ + printf("UNIMPLEMENTED '%s' op %02x s %d bxtype %02x\n", s, OP, S, BXTYPE); \ + regdump(instruction, last_pc, 1); \ + return; \ +} + +#define EVAL_COND(cc) \ +{ \ + switch (cc) { \ + case 0x0: cond = (Z == 1); break; \ + case 0x1: cond = (Z == 0); break; \ + case 0x2: cond = (C == 1); break; \ + case 0x3: cond = (C == 0); break; \ + case 0x4: cond = (N == 1); break; \ + case 0x5: cond = (N == 0); break; \ + case 0x6: cond = (V == 1); break; \ + case 0x7: cond = (V == 0); break; \ + case 0x8: cond = (C == 1 && Z == 0); break; \ + case 0x9: cond = (C == 0 || Z == 1); break; \ + case 0xa: cond = (N == V); break; \ + case 0xb: cond = (N != V); break; \ + case 0xc: cond = (Z == 0 && N == V); break; \ + case 0xd: cond = (Z == 1 || N != V); break; \ + case 0xe: cond = (1); break; \ + case 0xf: cond = (0xf); break; \ + } \ +} + +u32 instruction; +u32 last_pc; + +void simhandler(int sig) +{ + extern void restoremode(); + + psignal(sig, "forth"); + regdump(instruction, last_pc, 1); + restoremode(); + exit(1); +} + + // alf = find(adr, len, link, origin); +u32 * +find(u8 *adr, u32 len, u32 *link, void *origin) +{ + u8 *wp, *np; + u32 namelen; + + while (link != origin) { + link -= 1; // Move from code field to link field + np = (u8 *)link - 1; + namelen = (*np) & 0x1f; + if (namelen == len) { + np -= namelen; + wp = adr; + while (namelen--) { + if (*np++ != *wp++) { + break; + } + } + if (namelen == -1) { + return (link); + } + } + link = (u32 *)*link; + } + return ((u32 *)0); +} + +void +simulate(u8 *mem, u32 start, u32 header, u32 syscall_vec, + u32 memtop, u32 argc, u32 argv) +{ + // register u32 instruction; + register u32 res; + register u32 cond; + register u32 temp; + u32 indent = 0; + u32 name; + u32 namelen; + // u32 last_pc; + + signal(SIGBUS, simhandler); + signal(SIGSEGV, simhandler); + + APSR.all = 0; + PC = start + 8; // Stupid ARM. + r[0] = header; + r[1] = 0; // Tell Forth it is using the simulator + r[2] = memtop; + r[3] = argc; + SP = memtop; + *((u32 *)SP) = argv; + + while (1) { + instruction = MEM(u32, PC - 8); + last_pc = PC; +//#if TRACE + if (trace) + regdump(instruction, last_pc, 0); +//#endif + EVAL_COND(COND); + if (cond == 0xf) + UNIMP("unconditional"); + switch (OP) { +case 0x00: if (OP1 == 0 || OP2 == 0) { + INSTR("and"); SHFT(res); RD = RN & res; UPCC(RD); break; + } + switch (BXTYPE) { + case 0x9: INSTR("mul"); RN = RS * RM; UPCC(RN); break; + // P=0, U=0, bit22=0, W=0 - post-index, add offset, register, no writeback + case 0xb: + if (L) { + INSTR("ldrh"); + RD = MEM(u16, RN); + RN = RN + RM; + } else { + INSTR("strh"); + MEM(u16, RN) = RD; + RN = RN + RM; + } + break; + case 0xd: + if (L) { + INSTR("ldrsb"); + RD = MEM(s8, RN); + RN = RN + RM; + } else { + UNIMP("ldrd"); + } + break; + case 0xf: if (L) { + INSTR("ldrsh"); + RD = MEM(s16, RN); + RN = RN + RM; + } else { + UNIMP("strd"); + } + break; + default: UNIMP("BXTYPE"); break; + } break; +case 0x01: if (OP1 == 0 || OP2 == 0) { + INSTR("eor"); SHFT(res); RD = RN ^ res; UPCC(RD); break; + } + switch (BXTYPE) { + case 0x9: UNIMP("mla"); break; + // P=0, U=0, bit22=0, W=1 - post-index, add offset, register, writeback - UNPREDICTABLE (P=0, W=1) + case 0xb: UNIMP("ldrh"); break; // UNPREDICTABLE + case 0xd: UNIMP("ldrd"); break; // UNPREDICTABLE + case 0xf: UNIMP("ldrsh"); break; // UNPREDICTABLE + } break; +case 0x02: if (OP1 == 0 || OP2 == 0) { + INSTR("sub"); SHFT(res); SBB(RD, RN, res, 1); break; + } + switch (BXTYPE) { + // P=0, U=0, bit22=1, W=0 - post-index, add offset, immediate, no writeback + case 0xb: + if (L) { + INSTR("ldrh"); + RD = MEM(u16, RN); + RN = RN + IMMHL; + } else { + INSTR("strh"); + MEM(u16, RN) = RD; + RN = RN + IMMHL; + } + break; + case 0xd: + if (L) { + INSTR("ldrsb"); + RD = MEM(s8, RN); + RN = RN + IMMHL; + } else { + UNIMP("ldrd"); + } + break; + case 0xf: if (L) { + INSTR("ldrsh"); + RD = MEM(s16, RN); + RN = RN + IMMHL; + } else { + UNIMP("strd"); + } + break; + default: UNIMP("BXTYPE"); break; + } break; +case 0x03: if (OP1 == 0 || OP2 == 0) { + INSTR("rsb"); SHFT(res); SBB(RD, res, RN, 1); break; + } else { + switch (BXTYPE) { + case 0x1: + case 0x3: + case 0x5: + case 0x7: INSTR("rsb"); SHFT(res); SBB(RD, res, RN, 1); break; + case 0x9: UNIMP("mls"); break; + // P=0, U=0, bit22=1, W=1 - post-index, add offset, immediate, writeback - UNPREDICTABLE (P=0, W=1) + case 0xb: UNIMP("ldrh"); break; // UNPREDICTABLE + case 0xd: UNIMP("ldrd"); break; // UNPREDICTABLE + case 0xf: UNIMP("ldrsh"); break; // UNPREDICTABLE + } break; + } break; +case 0x04: if (OP1 == 0 || OP2 == 0) { + INSTR("add"); SHFT(res); ADC(RD, RN, res, 0); break; + } + switch (BXTYPE) { + // P=0, U=1, bit22=0, W=0 - post-index, subtract offset, register, no writeback + case 0xb: + if (L) { + INSTR("ldrh"); + RD = MEM(u16, RN); + RN = RN - RM; + } else { + INSTR("strh"); + MEM(u16, RN) = RD; + RN = RN - RM; + } + break; + case 0xd: + if (L) { + INSTR("ldrsb"); + RD = MEM(s8, RN); + RN = RN - RM; + } else { + UNIMP("ldrd"); + } + break; + case 0xf: if (L) { + INSTR("ldrsh"); + RD = MEM(s16, RN); + RN = RN - RM; + } else { + UNIMP("strd"); + } + break; + default: UNIMP("BXTYPE"); break; + } break; +case 0x05: if (OP1 == 0 || OP2 == 0) { + INSTR("adc"); SHFT(res); ADC(RD, RN, res, C); break; + } + switch (BXTYPE) { + // P=0, U=1, bit22=0, W=1 - post-index, subtract offset, register, writeback - UNPREDICTABLE (P=0, W=1) + case 0xb: UNIMP("ldrh"); break; // UNPREDICTABLE + case 0xd: UNIMP("ldrd"); break; // UNPREDICTABLE + case 0xf: UNIMP("ldrsh"); break; // UNPREDICTABLE + default: UNIMP("BXTYPE"); break; + } break; +case 0x06: if (OP1 == 0 || OP2 == 0) { + INSTR("sbc"); SHFT(res); +// printf("sbc RN %x res %x ~res %x C %x -- ", RN, res, ~(res), C); +// ADC(RD, RN, ~(res), C); +// printf("res %x\n", RD); +// printf("sbc RN %x res %x ~res %x C %x -- ", RN, res, ~(res), C); + SBB(RD, RN, res, C); +// printf("res %x\n", RD); +break; + } else { + switch (BXTYPE) { + case 0x1: + case 0x3: + case 0x5: + case 0x7: INSTR("sbc"); SHFT(res); SBB(RD, res, RN, C); break; + case 0x9: UNIMP("smull"); break; + // P=0, U=1, bit22=1, W=0 - post-index, subtract offset, immediate, no writeback + case 0xb: + if (L) { + INSTR("ldrh"); + RD = MEM(u16, RN); + RN = RN - IMMHL; + } else { + INSTR("strh"); + MEM(u16, RN) = RD; + RN = RN - IMMHL; + } + break; + case 0xd: + if (L) { + INSTR("ldrsb"); + RD = MEM(s8, RN); + RN = RN - IMMHL; + } else { + UNIMP("ldrd"); + } + break; + case 0xf: if (L) { + INSTR("ldrsh"); + RD = MEM(s16, RN); + RN = RN - IMMHL; + } else { + UNIMP("strd"); + } + break; + default: UNIMP("BXTYPE"); break; + } break; + } break; +case 0x07: if (OP1 == 0 || OP2 == 0) { + INSTR("rsc"); SHFT(res); SBB(RD, res, RN, C); break; + } else { + switch (BXTYPE) { + case 0x1: + case 0x3: + case 0x5: + case 0x7: INSTR("rsc"); SHFT(res); SBB(RD, res, RN, C); break; + case 0x9: UNIMP("smlal"); break; + // P=0, U=1, bit22=1, W=1 - post-index, subtract offset, immediate, writeback - UNPREDICTABLE (P=0, W=1) + case 0xb: UNIMP("ldrh"); break; // UNPREDICTABLE + case 0xd: UNIMP("ldrd"); break; // UNPREDICTABLE + case 0xf: UNIMP("ldrsh"); break; // UNPREDICTABLE + default: UNIMP("BXTYPE"); break; + } break; + } break; +case 0x08: switch (BXTYPE) { + case 0x0: INSTR("mrs"); RD = APSR.all; break; + case 0x5: UNIMP("qadd"); break; + case 0x8: + case 0xa: + case 0xc: + case 0xe: UNIMP("smlabb"); break; + // P=1, U=0, bit22=0, W=0 - offset/pre-index, subtract offset, register, no writeback + case 0xb: + if (L) { + INSTR("ldrh"); + RD = MEM(u16, RN - RM); + } else { + INSTR("strh"); + MEM(u16, RN - RM) = RD; + } + break; + case 0xd: + if (L) { + INSTR("ldrsb"); + RD = MEM(s8, RN - RM); + } else { + UNIMP("ldrd"); + } + break; + case 0xf: if (L) { + INSTR("ldrsh"); + RD = MEM(s16, RN - RM); + } else { + UNIMP("strd"); + } + break; + default: UNIMP("BXTYPE"); break; + } break; +case 0x09: switch (BXTYPE) { + case 0x0: UNIMP("msr"); break; + case 0x1: INSTR("bx"); PC = RM; break; + case 0x2: INSTR("bxj"); PC = RM; break; + case 0x3: INSTR("blx"); if (LINK) LR = PC - 4; PC = RM; break; + case 0x5: UNIMP("qsub"); break; + case 0x7: UNIMP("bkpt"); break; + case 0x8: + case 0xa: + case 0xc: + case 0xe: UNIMP("smlawb"); break; + // P=1, U=0, bit22=0, W=1 - offset/pre-index, subtract offset, register, writeback + case 0xb: + if (L) { + INSTR("ldrh"); + temp = RN - RM; + RD = MEM(u16, temp); + RN = temp; + } else { + INSTR("strh"); + temp = RN - RM; + MEM(u16, temp) = RD; + RN = temp; + } + break; + case 0xd: + if (L) { + INSTR("ldrsb"); + temp = RN - RM; + RD = MEM(s8, temp); + RN = temp; + } else { + UNIMP("ldrd"); + } + break; + case 0xf: if (L) { + INSTR("ldrsh"); + temp = RN - RM; + RD = MEM(s16, temp); + RN = temp; + } else { + UNIMP("strd"); + } + break; + default: UNIMP("BXTYPE"); break; + } break; +case 0x0a: if (OP1 == 0 || OP2 == 0) { + INSTR("cmp"); SHFT(res); SBB(res, RN, res, 1); break; + } + switch (BXTYPE) { + case 0x5: UNIMP("qdadd"); break; + case 0x8: + case 0xa: + case 0xc: + case 0xe: UNIMP("smlalbb"); break; + // P=1, U=0, bit22=1, W=0 - offset/pre-index, subtract offset, immediate, no writeback + case 0xb: + if (L) { + INSTR("ldrh"); + RD = MEM(u16, RN - IMMHL); + } else { + INSTR("strh"); + MEM(u16, RN - IMMHL) = RD; + } + break; + case 0xd: + if (L) { + INSTR("ldrsb"); + RD = MEM(s8, RN - IMMHL); + } else { + UNIMP("ldrd"); + } + break; + case 0xf: if (L) { + INSTR("ldrsh"); + RD = MEM(s16, RN - IMMHL); + } else { + UNIMP("strd"); + } + break; + default: UNIMP("BXTYPE"); break; + } break; +case 0x0b: if (OP1 == 0 || OP2 == 0) { + if (S) { + INSTR("cmn"); SHFT(res); ADC(res, RN, res, 0); break; + } else { + // "You don't need this instruction anyway." + // --mjterave@gmail.com + UNIMP("clz"); break; + } + } + switch (BXTYPE) { + case 0x5: UNIMP("qdsub"); break; + case 0x8: + case 0xa: + case 0xc: + case 0xe: UNIMP("smulbb"); break; + // P=1, U=0, bit22=1, W=1 - offset/pre-index, subtract offset, immediate, writeback + case 0xb: + if (L) { + INSTR("ldrh"); + temp = RN - IMMHL; + RD = MEM(u16, temp); + RN = temp; + } else { + INSTR("strh"); + temp = RN - IMMHL; + MEM(u16, temp) = RD; + RN = temp; + } + break; + case 0xd: + if (L) { + INSTR("ldrsb"); + temp = RN - IMMHL; + RD = MEM(s8, temp); + RN = temp; + } else { + UNIMP("ldrd"); + } + break; + case 0xf: if (L) { + INSTR("ldrsh"); + temp = RN - IMMHL; + RD = MEM(s16, temp); + RN = temp; + } else { + UNIMP("strd"); + } + break; + default: UNIMP("BXTYPE"); break; + } break; +case 0x0c: if (OP1 == 0 || OP2 == 0) { + INSTR("orr"); SHFT(res); RD = RN | res; UPCC(res); break; + } else { + switch (BXTYPE) { + case 0x1: + case 0x3: + case 0x5: + case 0x7: INSTR("orr"); SHFT(res); RD = RN | res; UPCC(res); + break; + case 0x9: UNIMP("ldrex"); break; + // P=1, U=0, bit22=0, W=0 - offset/pre-index, subtract offset, register, no writeback + case 0xb: + if (L) { + INSTR("ldrh"); + RD = MEM(u16, RN + RM); + } else { + INSTR("strh"); + MEM(u16, RN + RM) = RD; + } + break; + case 0xd: + if (L) { + INSTR("ldrsb"); + RD = MEM(s8, RN + RM); + } else { + UNIMP("ldrd"); + } + break; + case 0xf: if (L) { + INSTR("ldrsh"); + RD = MEM(s16, RN + RM); + } else { + UNIMP("strd"); + } + break; + default: UNIMP("BXTYPE"); break; + } break; + } break; +case 0x0d: switch (BXTYPE) { + case 0x0: + if (instruction == 0xe1a00000) { + INSTR("nop"); break; + } else if (IMM5 == 0) { + if (instruction == 0xe1a0f009) { // mov pc,up i.e. the part of NEXT at the end of each code word + INSTR("NEXT"); + } else { + INSTR("mov"); + } + RD = RM; UPCC(RD); break; + } /* else fall through */ + case 0x8: + case 0x1: INSTR("lsl"); SHFT(RD); UPCC(RD); break; + case 0x2: + case 0xa: + case 0x3: INSTR("lsr"); SHFT(RD); UPCC(RD); break; + case 0x4: + case 0xc: + case 0x5: INSTR("asr"); SHFT(RD); UPCC(RD); break; + case 0x6: + case 0xe: + case 0x7: INSTR("ror"); SHFT(RD); UPCC(RD); break; + case 0x9: UNIMP("ldrexd"); break; + // P=1, U=1, bit22=0, W=1 - offset/pre-index, add offset, register, writeback + case 0xb: + if (L) { + INSTR("ldrh"); + temp = RN + RM; + RD = MEM(u16, temp); + RN = temp; + } else { + INSTR("strh"); + temp = RN + RM; + MEM(u16, temp) = RD; + RN = temp; + } + break; + case 0xd: + if (L) { + INSTR("ldrsb"); + temp = RN + RM; + RD = MEM(s8, temp); + RN = temp; + } else { + UNIMP("ldrd"); + } + break; + case 0xf: if (L) { + INSTR("ldrsh"); + temp = RN + RM; + RD = MEM(s16, temp); + RN = temp; + } else { + UNIMP("strd"); + } + break; + default: UNIMP("BXTYPE"); break; + }; break; +case 0x0e: if (OP1 == 0 || OP2 == 0) { + INSTR("bic"); SHFT(res); RD = RN & ~res; UPCC(RD); break; + } + switch (BXTYPE) { + case 0x9: UNIMP("ldrexb"); break; + // P=1, U=1, bit22=1, W=0 - offset/pre-index, add offset, immediate, no writeback + case 0xb: + if (L) { + INSTR("ldrh"); + RD = MEM(u16, RN + IMMHL); + } else { + INSTR("strh"); + MEM(u16, RN + IMMHL) = RD; + } + break; + case 0xd: + if (L) { + INSTR("ldrsb"); + RD = MEM(s8, RN + IMMHL); + } else { + UNIMP("ldrd"); + } + break; + case 0xf: if (L) { + INSTR("ldrsh"); + RD = MEM(s16, RN + IMMHL); + } else { + UNIMP("strd"); + } + break; + } break; +case 0x0f: if (OP1 == 0 || OP2 == 0) { + INSTR("mvn"); SHFT(res); RD = ~res; UPCC(RD); break; + } else { + switch (BXTYPE) { + case 0x9: UNIMP("ldrexh"); break; + // P=1, U=1, bit22=1, W=1 - offset/pre-index, add offset, immediate, writeback + case 0xb: + if (L) { + INSTR("ldrh"); + temp = RN + IMMHL; + RD = MEM(u16, temp); + RN = temp; + } else { + INSTR("strh"); + temp = RN + IMMHL; + MEM(u16, temp) = RD; + RN = temp; + } + break; + case 0xd: + if (L) { + INSTR("ldrsb"); + temp = RN + IMMHL; + RD = MEM(s8, temp); + RN = temp; + } else { + UNIMP("ldrd"); + } + break; + case 0xf: if (L) { + INSTR("ldrsh"); + temp = RN + IMMHL; + RD = MEM(s16, temp); + RN = temp; + } else { + UNIMP("strd"); + } + break; + default: UNIMP("BXTYPE"); break; + } break; + } break; +case 0x10: INSTR("and"); RD = RN & IMM32; UPCC(RD); break; +case 0x11: INSTR("eor"); RD = RN ^ IMM32; UPCC(RD); break; +case 0x12: INSTR("sub"); SBB(RD, RN, IMM32, 1); break; +case 0x13: INSTR("rsb"); SBB(RD, IMM32, RN, 1); break; +case 0x14: /* if (instruction == 0xe2809020) trace = 0; */ + INSTR("add"); ADC(RD, RN, IMM32, 0); break; +case 0x15: INSTR("adc"); ADC(RD, RN, IMM32, C); break; +case 0x16: INSTR("sbc"); SBB(RD, IMM32, RN, C); break; +case 0x17: INSTR("rsc"); SBB(RD, IMM32, RN, C); break; +case 0x18: INSTR("mov"); RD = IMM16; break; +case 0x19: switch (BXTYPE) { + case 0x0: INSTR("nop"); break; + case 0x1: + INSTR("wrc"); + if (RN == -2) { + printf("Tracing on\n"); + trace = 1; + } else if (RN == -1) { +// trace = 1; +// printf("find %x %x %x %x\n",r[2], r[1], r[0], r[3]); + // alf = find(u8 *adr, u32 len, u32 *link, void *origin); + r[0] = (u32)find((u8 *)r[2], r[1], (u32 *)r[0], (u8 *)r[3]); +// printf("returns %x\n", r[0]); + } else { + /* Handle Forth wrapper calls - the call# is in RN */ + r[0] = (*(long (*) ())(*(long *)(syscall_vec + RN))) + (r[0],r[1],r[2],r[3],r[4],r[5]); + } + break; + + case 0xf: UNIMP("dbg"); break; + default: UNIMP("msr"); break; + } break; +case 0x1a: if (S) { + INSTR("cmp"); SBB(res, RN, IMM32, 1); break; + } else { + INSTR("movt"); RD = (IMM16 << 16) | (RD & 0xffff); break; + } +case 0x1b: INSTR("cmn"); ADC(res, RN, IMM32, 0); break; +case 0x1c: INSTR("orr"); RD = RN | IMM32; UPCC(RD); break; +case 0x1d: INSTR("mov"); RD = IMM32; UPCC(RD); break; +case 0x1e: INSTR("bic"); RD = RN & (~IMM32); UPCC(RD); break; +case 0x1f: INSTR("mvn"); RD = ~IMM32; UPCC(RD); break; +case 0x20: +case 0x21: if (L) { + INSTR("ldr"); RD = MEM(u32, RN); RN -= IMM12; + } else { + INSTR("str"); MEM(u32, RN) = RD; RN -= IMM12; + } break; +case 0x22: +case 0x23: if (L) { + INSTR("ldrb"); RD = MEM(u8, RN); RN -= IMM12; + } else { + INSTR("strb"); MEM(u8, RN) = RD; RN -= IMM12; + } break; +case 0x24: if (L) { + if (UFIELD(19, 4) == 0xd) { + INSTR("pop"); RD = MEM(u32, RN); RN += IMM12; + } else { + if (instruction == 0xe49cf004) { // ldr pc,[ip],#4 i.e. the guts of NEXT + INSTR("DONEXT"); + } else if (instruction == 0xe49ca004) { // ldr tos,[ip],#4 i.e. the guts of (lit) and (') + INSTR("DOLIT"); + } else { + if (instruction == 0xe49bc004) { indent--; if (indent < 0) indent = 0; } + INSTR("ldr"); + } + RD = MEM(u32, RN); RN += IMM12; + if (trace) { + // If NEXT or ('), show the name of the word + if ((instruction == 0xe49cf004) || (instruction == 0xe49ca004)) { + name = RD - 5; + // If name is not in the dictionary area, it is probably a numeric literal + if (name >= r[9] && ((name - r[9]) < 0x100000)) { + namelen = *(char *)name & 0x3f; + name = name - namelen; + // Indent with * for EMACS outline mode - handy for hiding subordinate calls +// for (temp = 0; temp < indent; temp++) +// putchar('*'); + while (namelen--) + putchar(*(char *)name++); + printf(" Stack: %x %x %x %x indent %x\n" , + ((u32 *)r[13])[2], ((u32 *)r[13])[1], ((u32 *)r[13])[0], r[10], indent); + } + } + } + } + } else { + INSTR("str"); MEM(u32, RN) = RD; RN += IMM12; + } break; +case 0x25: if (L) { + INSTR("ldr"); RD = MEM(u32, RN); RN += IMM12; + } else { + INSTR("str"); MEM(u32, RN) = RD; RN += IMM12; + } break; +case 0x26: +case 0x27: if (L) { + INSTR("ldrb"); RD = MEM(u8, RN); RN += IMM12; + } else { + INSTR("strb"); MEM(u8, RN) = RD; RN += IMM12; + } break; +case 0x28: if (L) { + INSTR("ldr"); RD = MEM(u32, RN - IMM12); break; + } else { + INSTR("str"); MEM(u32, RN - IMM12) = RD; break; + } break; +case 0x29: if (L) { + INSTR("ldr"); RN -= IMM12; RD = MEM(u32, RN); break; + } else { + if (instruction == 0xe52bc004) indent++; // DOCOLON + INSTR("str"); RN -= IMM12; MEM(u32, RN) = RD; + break; + } break; +case 0x2a: if (L) { + INSTR("ldrb"); RD = MEM(u8, RN - IMM12); break; + } else { + INSTR("strb"); MEM(u8, RN - IMM12) = RD; break; + } break; +case 0x2b: if (L) { + INSTR("ldrb"); RN -= IMM12; RD = MEM(u8, RN); break; + } else { + INSTR("strb"); RN -= IMM12; MEM(u8, RN) = RD; break; + } break; +case 0x2c: if (L) { + INSTR("ldr"); RD = MEM(u32, RN + IMM12); break; + } else { + INSTR("str"); MEM(u32, RN + IMM12) = RD; break; + } break; +case 0x2d: if (L) { + INSTR("ldr"); RN += IMM12; RD = MEM(u32, RN); break; + } else { + INSTR("str"); RN += IMM12; MEM(u32, RN) = RD; break; + } break; +case 0x2e: if (L) { + INSTR("ldrb"); RD = MEM(u8, RN + IMM12); break; + } else { + INSTR("strb"); MEM(u8, RN + IMM12) = RD; break; + } break; +case 0x2f: if (L) { + INSTR("ldrb"); RN += IMM12; RD = MEM(u8, RN); break; + } else { + INSTR("strb"); RN += IMM12; MEM(u8, RN) = RD; break; + } break; +case 0x30: +case 0x31: if (OP1) { + UNIMP("mcr"); break; + } else if (L) { + INSTR("ldr"); SHFT(res); RD = MEM(u32, RN); RN -= res; break; + } else { + INSTR("str"); SHFT(res); MEM(u32, RN) = RD; RN -= res; break; + } break; +case 0x32: +case 0x33: if (OP1) { + UNIMP("mcr"); break; + } else if (L) { + INSTR("ldrb"); SHFT(res); RD = MEM(u8, RN); RN -= res; break; + } else { + INSTR("strb"); SHFT(res); MEM(u8, RN) = RD; RN -= res; break; + } break; +case 0x34: +case 0x35: if (OP1) { + UNIMP("mcr"); break; + } else if (L) { + INSTR("ldr"); SHFT(res); RD = MEM(u32, RN); RN += res; break; + } else { + INSTR("str"); SHFT(res); MEM(u32, RN) = RD; RN += res; break; + } break; +case 0x36: +case 0x37: if (OP1) { + UNIMP("mcr"); break; + } else if (L) { + INSTR("ldrb"); SHFT(res); RD = MEM(u8, RN); RN += res; break; + } else { + INSTR("strb"); SHFT(res); MEM(u8, RN) = RD; RN += res; break; + } break; +case 0x38: if (OP1) { + UNIMP("smlad"); break; + } else if (L) { + INSTR("ldr"); SHFT(res); RD = MEM(u32, RN - res); break; + } else { + INSTR("str"); SHFT(res); MEM(u32, RN - res) = RD; break; + } break; +case 0x39: if (L) { + INSTR("ldr"); SHFT(res); RN -= res; RD = MEM(u32, RN); break; + } else { + INSTR("str"); SHFT(res); RN -= res; MEM(u32, RN) = RD; break; + } break; +case 0x3a: if (OP1) { + UNIMP("smlald"); break; + } else if (L) { + INSTR("ldrb"); SHFT(res); RD = MEM(u8, RN - res); break; + } else { + INSTR("strb"); SHFT(res); MEM(u8, RN - res) = RD; break; + } break; +case 0x3b: if (L) { + INSTR("ldrb"); SHFT(res); RN -= res; RD = MEM(u8, RN); break; + } else { + INSTR("strb"); SHFT(res); RN -= res; MEM(u8, RN) = RD; break; + } +case 0x3c: if (L) { + INSTR("ldr"); SHFT(res); RD = MEM(u32, RN + res); break; + } else { + INSTR("str"); SHFT(res); MEM(u32, RN + res) = RD; break; + } +case 0x3d: if (OP1) { + UNIMP("sbfx"); break; + } else if (L) { + INSTR("ldr"); SHFT(res); RN += res; RD = MEM(u32, RN); break; + } else { + INSTR("str"); SHFT(res); RN += res; MEM(u32, RN) = RD; break; + } break; +case 0x3e: if (OP1) { + if (UFIELD(3, 4) == 0xf) { + INSTR("bfc"); RD &= ~BF(MSB, LSB); + } else { + INSTR("bfi"); + RD &= ~BF(MSB, LSB); + RD |= RN & ~BF(MSB, LSB); + } + } else if (L) { + INSTR("ldrb"); SHFT(res); RD = MEM(u8, RN + res); + } else { + INSTR("strb"); SHFT(res); MEM(u8, RN + res) = RD; + } break; +case 0x3f: if (L) { + INSTR("ldrb"); SHFT(res); RN += res; RD = MEM(u8, RN); break; + } else { + INSTR("strb"); SHFT(res); RN += res; MEM(u8, RN) = RD; break; + } break; +case 0x40: +case 0x41: { u32 base = RN; + u32 reglist = UFIELD(15, 16); + s32 reg; + if (L) { + INSTR("ldmda"); + } else { + INSTR("stmda"); + } + for (reg = 15; reg >= 0; reg--) { + if ((1 << reg) & reglist) { + if (L) { + r[reg] = MEM(u32, base); + } else { + MEM(u32, base) = r[reg]; + } + base -= 4; + } + } + if (W) RN = base; + } break; +case 0x42: UNIMP("xxx"); +case 0x43: UNIMP("xxx"); +case 0x44: +case 0x45: { u32 base = RN; + u32 reglist = UFIELD(15, 16); + s32 reg; + if (L) { + INSTR("ldm"); + } else { + INSTR("stm"); + } + for (reg = 0; reg < 16; reg++) { + if ((1 << reg) & reglist) { + if (L) { + r[reg] = MEM(u32, base); + } else { + MEM(u32, base) = r[reg]; + } + base += 4; + } + } + if (W) RN = base; + } break; +case 0x46: UNIMP("xxx"); +case 0x47: UNIMP("xxx"); +case 0x48: +case 0x49: { u32 base = RN; + u32 reglist = UFIELD(15, 16); + s32 reg; + if (L) { + INSTR("ldmdb"); + } else { + INSTR("stmdb"); + } + for (reg = 15; reg >= 0; reg--) { + if ((1 << reg) & reglist) { + base -= 4; + if (L) { + r[reg] = MEM(u32, base); + } else { + MEM(u32, base) = r[reg]; + } + } + } + if (W) RN = base; + } break; +case 0x4a: UNIMP("xxx"); break; +case 0x4b: UNIMP("xxx"); break; +case 0x4c: +case 0x4d: { u32 base = RN + 4; + u32 reglist = UFIELD(15, 16); + s32 reg; + if (L) { + INSTR("ldmib"); + } else { + INSTR("stmib"); + } + for (reg = 0; reg < 16; reg++) { + if ((1 << reg) & reglist) { + if (L) { + r[reg] = MEM(u32, base); + } else { + MEM(u32, base) = r[reg]; + } + base += 4; + } + } + if (W) RN = base; + } break; +case 0x4e: UNIMP("xxx"); break; +case 0x4f: UNIMP("xxx"); break; +case 0x50: +case 0x51: +case 0x52: +case 0x53: +case 0x54: +case 0x55: +case 0x56: +case 0x57: INSTR("b"); BTGT; break; +case 0x58: +case 0x59: +case 0x5a: +case 0x5b: +case 0x5c: +case 0x5d: +case 0x5e: +case 0x5f: INSTR("bl"); LR = PC - 4; BTGT; break; +case 0x60: +case 0x61: UNIMP("stc"); break; +case 0x62: UNIMP("mcrr"); break; +case 0x63: +case 0x64: +case 0x65: +case 0x66: +case 0x67: +case 0x68: +case 0x69: +case 0x6a: +case 0x6b: +case 0x6c: +case 0x6d: +case 0x6e: UNIMP("stc"); break; +case 0x6f: UNIMP("ldc"); break; +case 0x70: +case 0x71: +case 0x72: +case 0x73: +case 0x74: +case 0x75: +case 0x76: +case 0x77: UNIMP("cdp"); break; +case 0x78: +case 0x79: +case 0x7a: +case 0x7b: +case 0x7c: +case 0x7d: +case 0x7e: +case 0x7f: UNIMP("svc"); break; + } // switch (OP) + if (PC == last_pc) + PC += 4; + else // branch or move + PC += 8; + } // while (1) +} + +// LICENSE_BEGIN +// Copyright (c) 2007 FirmWorks +// Copyright 2010 Apple, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// LICENSE_END
Modified: cpu/arm/assem.fth ============================================================================== --- cpu/arm/assem.fth Thu Dec 23 21:34:52 2010 (r2096) +++ cpu/arm/assem.fth Sat Jan 1 10:56:55 2011 (r2097) @@ -990,6 +990,9 @@ : adr ( -- ) true (set) ; : set ( -- ) false (set) ;
+\ Wrapper Call - FirmWorks pseudo-op for armsim wrapper calls +: wrc ( -- ) h# 03200010 {cond} init-operands get-r16 !op ; + : nop32 ( -- ) h# 0320f000 {cond} !op ; : yield ( -- ) h# 0320f001 {cond} !op ; : wfe ( -- ) h# 0320f002 {cond} !op ;
Modified: cpu/arm/build/Makefile ============================================================================== --- cpu/arm/build/Makefile Thu Dec 23 21:34:52 2010 (r2096) +++ cpu/arm/build/Makefile Sat Jan 1 10:56:55 2011 (r2097) @@ -1,4 +1,9 @@ +BASEDIR= `(cd ../../../; pwd;)` + OS := $(shell uname) +HOSTCPU= $(shell ${BASEDIR}/forth/lib/hostcpu.sh) +HOSTDIR= ../${HOSTCPU}/${OS} +BUILDSH= ${BASEDIR}/forth/lib/build.sh
all: basefw.dic
@@ -9,8 +14,11 @@ ../${OS}/forth: @make -C ../${OS} forth
-build: ../${OS}/forth - @ln -sf ../${OS}/forth $@ +build: + @ln -sf ${BUILDSH} build + +# build: ../${OS}/forth +# @ln -sf ../${OS}/forth $@
%.dic: FORCE build ./build $@
Modified: cpu/arm/build/builder.dic ============================================================================== Binary file (source and/or target). No diff available.
Modified: cpu/arm/disassem.fth ============================================================================== --- cpu/arm/disassem.fth Thu Dec 23 21:34:52 2010 (r2096) +++ cpu/arm/disassem.fth Sat Jan 1 10:56:55 2011 (r2097) @@ -154,12 +154,21 @@ endcase {<cond>} ; +\ Wrapper call pseudo-op - used to request system functions from armsim +: .wrc ( -- ) + ." wrc" + {<cond>} op-col .rn +; : .mrs/sr ( -- ) d#21 bit? if \ MSR - instruction @ h# 00cf.fff8 and h# 00000.f000 = if + instruction @ h# 00cf.fff8 and h# 0000.f000 = if .event exit then + instruction @ h# 00c0.fff8 and h# 0000.0010 = if + .wrc + exit + then ." msr" {<cond>} op-col .psr .fields ., .r/imm else \ MRS
Modified: cpu/arm/sys.fth ============================================================================== --- cpu/arm/sys.fth Thu Dec 23 21:34:52 2010 (r2096) +++ cpu/arm/sys.fth Sat Jan 1 10:56:55 2011 (r2097) @@ -28,11 +28,13 @@
psh ip,rp \ This register may be clobbered ldr r6,'user syscall-vec \ Get address of system call table - add r6,r6,tos \ Call through vector - ldr r6,[r6] + cmp r6,#0 + wrceq tos \ For the simulator, we execute a fake instruction + addne r6,r6,tos \ Call through vector + ldrne r6,[r6]
- mov lk,pc \ Return address - mov pc,r6 + movne lk,pc \ Return address + movne pc,r6 \ ldr pc,[r6,tos] \ Call through vector
str r0,'user sysretval \ Save the result @@ -73,10 +75,31 @@ ; ' sys-init-io is init-io
-: sys-init ; \ Environment initialization chain +code (wrapper-find-next) ( adr len link origin -- adr len alf true | adr len false ) + mov r3,tos \ origin in r3 + ldmia sp,{r0,r1,r2} \ r0: link, r1: len, r2: adr + ldr r0,[r0] \ Dereference first link in threads area + mvn r4,#0 \ -1 in r4 - tells the wrapper to do the find thing + wrc r4 + cmp r0,#0 + strne r0,[sp] \ Found: alf on memory stack (second item) + mvnne tos,#0 \ Found: true in top of stack register + inceq sp,1cell \ Not found - remove link from memory stack + moveq tos,#0 \ Not found - false in top of stack register +c; +: wrapper-find-next ( adr len link -- adr len alf true | adr len false ) + origin (wrapper-find-next) +; +\ Override $find-next with the wrapper accelerator version if we are +\ hosted under armsim +: sys-init ( -- ) + syscall-vec @ 0= if ['] wrapper-find-next is $find-next then +; + ' sys-init is init-environment decimal
+ \ LICENSE_BEGIN \ Copyright (c) 1994 FirmWorks \
Modified: cpu/x86/Darwin/Makefile ============================================================================== --- cpu/x86/Darwin/Makefile Thu Dec 23 21:34:52 2010 (r2096) +++ cpu/x86/Darwin/Makefile Sat Jan 1 10:56:55 2011 (r2097) @@ -52,8 +52,11 @@ inflate.o: ${ZIPDIR}/inflate.c ${CC} -c -m32 -O0 -fpic $< -o $@
+# Well, we're not going to get objcopy in a generic OS X environment, so +# let's just fake it. ../build/inflate.bin: inflate.o - ${OBJCOPY} -O binary $< $@ + # ${OBJCOPY} -O binary $< $@ + dd if=$< of=$@ bs=256 skip=1
%.o: ${WRDIR}/%.c ${CC} -c ${CFLAGS} -I${ZIPDIR} $< -o $@
Added: cpu/x86/Darwin/Makefile.armforth ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ cpu/x86/Darwin/Makefile.armforth Sat Jan 1 10:56:55 2011 (r2097) @@ -0,0 +1,74 @@ +# Wrapper makefile for x86 Mac OS X / Darwin + +BP=../../.. + +# Flags for the simulator version +OPT = -O +CFLAGS = -g -m32 -DARMSIM -DTARGET_ARM -DARM + +# Extra CFLAGS needed by Darwin hosts. GCC doesn't define __unix__ here, +# so we must include it ourselves. +CFLAGS += -D__unix__=1 -Wimplicit-function-declaration +#CFLAGS += -DUSE_XCB + +WRTAIL = forth/wrapper +WRDIR = ${BP}/${WRTAIL} +ZIPTAIL = ${WRTAIL}/zip +ZIPDIR = ${BP}/${ZIPTAIL} +ARMDIR = ${BP}/cpu/arm + +ZIPOBJS = zipmem.o deflate.o trees.o bits.o util.o inflate.o + +OBJS = wrapsim.o armsim.o logger.o ${ZIPOBJS} +TRACEOBJS = wrapsim.o armsim.trace.o logger.o ${ZIPOBJS} +SIMROMOBJS = simrom.o armsim.simrom.o + +# Apple's GCC is a bit brain-dead. It's probably best to install gcc43 and +# binutils from macports. See http://macports.macforge.net for how to install +# and use macports. At the very least, binutils from macports seems to be +# required. + +# The default compiler on Mac OS X (as of 10.5 anyway) does not honor -fpic. +# GCC will warn about -fpic not being supported, assumes you meant -fPIC, +# and switches to that. That should be okay, but if you're concerned about it +# I'm providing this already defined override for ${CC}. To use it, just +# uncomment it, or pass CC= on the command line. This is here to make things +# easier for us lazy people. +#CC = /opt/local/bin/gcc-mp-4.3 + +all: armforth armforth.trace + +armforth: $(OBJS) + $(CC) $(LFLAGS) $(OBJS) -o $@ + +armforth.trace: $(TRACEOBJS) + $(CC) $(LFLAGS) $(TRACEOBJS) -o $@ + +simrom: $(SIMROMOBJS) + $(CC) $(LFLAGS) $(SIMROMOBJS) -o $@ + +wrapsim.o: ${WRDIR}/wrapper.c + ${CC} -c ${CFLAGS} $< -o $@ + +%.o: ${WRDIR}/%.c + ${CC} -c ${CFLAGS} $< -o $@ + +%.o: ${ZIPDIR}/%.c + ${CC} -c ${CFLAGS} -I${ZIPDIR} $< -o $@ + +armsim.o: $(ARMDIR)/armsim.c + $(CC) $(OPT) $(CFLAGS) -DARGREGS -DSIMNEXT -c $< -o $@ + +armsim.trace.o: $(ARMDIR)/armsim.c + $(CC) $(OPT) $(CFLAGS) -DARGREGS -DSIMNEXT -DTRACE=1 -c $< -o $@ + +armsim.simrom.o: $(ARMDIR)/armsim.c + $(CC) $(CFLAGS) -DARGREGS -DSIMNEXT -DTRACE=1 -DSIMROM -c $< -o $@ + +simrom.o: $(ARMDIR)/simrom.c + $(CC) $(CFLAGS) -DARGREGS -DSIMNEXT -DTRACE=1 -DSIMROM -c $< -o $@ + +clean: + @rm -f *.o armforth armforth.trace + +FRC:
Added: cpu/x86/Linux/Makefile.armsim ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ cpu/x86/Linux/Makefile.armsim Sat Jan 1 10:56:55 2011 (r2097) @@ -0,0 +1,56 @@ +# Wrapper makefile for x86 Mac OS X / Darwin + +BP=../../.. + +# Flags for the simulator version +OPT = -O +CFLAGS = -g -m32 -DARMSIM -DTARGET_ARM -DARM + +WRTAIL = forth/wrapper +WRDIR = ${BP}/${WRTAIL} +ZIPTAIL = ${WRTAIL}/zip +ZIPDIR = ${BP}/${ZIPTAIL} +ARMDIR = ${BP}/cpu/arm + +ZIPOBJS = zipmem.o deflate.o trees.o bits.o util.o inflate.o + +OBJS = wrapsim.o armsim.o logger.o ${ZIPOBJS} +TRACEOBJS = wrapsim.o armsim.trace.o logger.o ${ZIPOBJS} +SIMROMOBJS = simrom.o armsim.simrom.o + +all: armforth armforth.trace + +armforth: $(OBJS) + $(CC) $(LFLAGS) $(OBJS) -o $@ + +armforth.trace: $(TRACEOBJS) + $(CC) $(LFLAGS) $(TRACEOBJS) -o $@ + +simrom: $(SIMROMOBJS) + $(CC) $(LFLAGS) $(SIMROMOBJS) -o $@ + +wrapsim.o: ${WRDIR}/wrapper.c + ${CC} -c ${CFLAGS} $< -o $@ + +%.o: ${WRDIR}/%.c + ${CC} -c ${CFLAGS} $< -o $@ + +%.o: ${ZIPDIR}/%.c + ${CC} -c ${CFLAGS} -I${ZIPDIR} $< -o $@ + +armsim.o: $(ARMDIR)/armsim.c + $(CC) $(OPT) $(CFLAGS) -DARGREGS -DSIMNEXT -c $< -o $@ + +armsim.trace.o: $(ARMDIR)/armsim.c + $(CC) $(OPT) $(CFLAGS) -DARGREGS -DSIMNEXT -DTRACE=1 -c $< -o $@ + +armsim.simrom.o: $(ARMDIR)/armsim.c + $(CC) $(CFLAGS) -DARGREGS -DSIMNEXT -DTRACE=1 -DSIMROM -c $< -o $@ + +simrom.o: $(ARMDIR)/simrom.c + $(CC) $(CFLAGS) -DARGREGS -DSIMNEXT -DTRACE=1 -DSIMROM -c $< -o $@ + +clean: + @rm -f *.o armforth armforth.trace + +FRC:
Modified: forth/wrapper/wrapper.c ============================================================================== --- forth/wrapper/wrapper.c Thu Dec 23 21:34:52 2010 (r2096) +++ forth/wrapper/wrapper.c Sat Jan 1 10:56:55 2011 (r2097) @@ -339,7 +339,6 @@ INTERNAL long path_open(); INTERNAL void keymode(); INTERNAL void keyqmode(); -INTERNAL void restoremode();
INTERNAL long f_open(), f_creat(); INTERNAL long f_close(), f_read(), f_write(); @@ -347,13 +346,16 @@ INTERNAL long f_lseek(); INTERNAL long f_crstr();
-#ifdef PPCSIM +#if defined(PPCSIM) || defined (ARMSIM) /* These are not INTERNAL because the PowerPC simulator uses then */ long c_key(); long s_bye(); + void simulate(); + void restoremode(); #else INTERNAL long c_key(); INTERNAL long s_bye(); + INTERNAL void restoremode(); #endif
INTERNAL long c_emit(); @@ -976,7 +978,7 @@
if (header.h_magic != CPU_MAGIC) { error("forth: Incorrect dictionary file header in ", dictfile); -/* XXX */ printf("%x %x\n", CPU_MAGIC, header.h_magic); +/* XXX */ printf("%x %x\n", CPU_MAGIC, (unsigned int) header.h_magic); exit(1); }
@@ -1003,6 +1005,10 @@ # ifdef PPCSIM printf("PowerPC Instruction Set Simulator\n"); printf("Copyright 1994 FirmWorks All rights reserved\n"); +# elif ARMSIM + printf("ARM Instruction Set Simulator\n"); + printf("Copyright 1994 FirmWorks All rights reserved\n"); + printf("Copyright 2010 Apple, Inc. All rights reserved\n"); # endif
loadaddr = (char *)m_alloc(dictsize); @@ -1056,10 +1062,14 @@ * exit with its return value as the status code. */
-#ifdef PPCSIM +#if defined(PPCSIM) simulate(0L, loadaddr+sizeof(header)+START_OFFSET, loadaddr, functions, ((long)loadaddr+dictsize - 16) & ~15, argc, argv, 1 /* 0=POWER, 1=PowerPC */); +#elif defined(ARMSIM) + // printf("loadaddr = 0x%x\n",loadaddr); + simulate(0L, loadaddr, loadaddr, functions, + ((long)loadaddr+dictsize - 16) & ~15, argc, argv); #else s_flushcache(loadaddr, dictsize); /* We're about to execute data! */ # ifdef TARGET_X86 @@ -1104,6 +1114,7 @@ s_bye(0L); # endif #endif + restoremode(); }
/* @@ -1516,7 +1527,7 @@ } }
-INTERNAL void +void restoremode() { initline();
Modified: forth/wrapper/zip/inflate.c ============================================================================== --- forth/wrapper/zip/inflate.c Thu Dec 23 21:34:52 2010 (r2096) +++ forth/wrapper/zip/inflate.c Sat Jan 1 10:56:55 2011 (r2097) @@ -172,7 +172,7 @@ * Return size of clear. */ int -inflate(struct workspace *wsptr, int nohdr, u_char* clear, u_char *compr) __attribute__((section ("text_inflate"))); +inflate(struct workspace *wsptr, int nohdr, u_char* clear, u_char *compr);
int inflate(struct workspace *wsptr, int nohdr, u_char* clear, u_char *compr)