[openfirmware] [commit] r2097 - cpu/arm cpu/arm/build cpu/x86/Darwin cpu/x86/Linux forth/wrapper forth/wrapper/zip

repository service svn at openfirmware.info
Sat Jan 1 10:56:55 CET 2011


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



More information about the openfirmware mailing list