summaryrefslogtreecommitdiff
path: root/sys/src/cmd/qi/run.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/qi/run.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/qi/run.c')
-rwxr-xr-xsys/src/cmd/qi/run.c205
1 files changed, 205 insertions, 0 deletions
diff --git a/sys/src/cmd/qi/run.c b/sys/src/cmd/qi/run.c
new file mode 100755
index 000000000..ea376b956
--- /dev/null
+++ b/sys/src/cmd/qi/run.c
@@ -0,0 +1,205 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <mach.h>
+#define Extern extern
+#include "power.h"
+
+
+void lfs(ulong);
+void lfd(ulong);
+void stfs(ulong);
+void stfd(ulong);
+/* indexed versions are in 31 */
+
+void addic(ulong);
+void addiccc(ulong);
+void addi(ulong);
+void addis(ulong);
+void andicc(ulong);
+void andiscc(ulong);
+void bcx(ulong);
+void bx(ulong);
+void cmpi(ulong);
+void cmpli(ulong);
+void lbz(ulong);
+void lha(ulong);
+void lhz(ulong);
+void lmw(ulong);
+void lwz(ulong);
+void mulli(ulong);
+void ori(ulong);
+void oris(ulong);
+void rlwimi(ulong);
+void rlwinm(ulong);
+void rlwnm(ulong);
+void sc(ulong);
+void stb(ulong);
+void sth(ulong);
+void stmw(ulong);
+void stw(ulong);
+void subfic(ulong);
+void twi(ulong);
+void xori(ulong);
+void xoris(ulong);
+
+Inst op0[] = {
+[3] {twi, "twi", Ibranch},
+[7] {mulli, "mulli", Iarith},
+[8] {subfic, "subfic", Iarith},
+[10] {cmpli, "cmpli", Iarith},
+[11] {cmpi, "cmpi", Iarith},
+[12] {addic, "addic", Iarith},
+[13] {addiccc, "addic.", Iarith},
+[14] {addi, "addi", Iarith},
+[15] {addis, "addis", Iarith},
+[16] {bcx, "bc⋯", Ibranch},
+[17] {sc, "sc", Isyscall},
+[18] {bx, "b⋯", Ibranch},
+/* group 19; branch unit */
+[20] {rlwimi, "rlwimi", Ilog},
+[21] {rlwinm, "rlwinm", Ilog},
+[23] {rlwnm, "rlwnm", Ilog},
+[24] {ori, "ori", Ilog},
+[25] {oris, "oris", Ilog},
+[26] {xori, "xori", Ilog},
+[27] {xoris, "xoris", Ilog},
+[28] {andicc, "andi.", Ilog},
+[29] {andiscc, "andis.", Ilog},
+/* group 31; integer & misc. */
+[32] {lwz, "lwz", Iload},
+[33] {lwz, "lwzu", Iload},
+[34] {lbz, "lbz", Iload},
+[35] {lbz, "lbzu", Iload},
+[36] {stw, "stw", Istore},
+[37] {stw, "stwu", Istore},
+[38] {stb, "stb", Istore},
+[39] {stb, "stbu", Istore},
+[40] {lhz, "lhz", Iload},
+[41] {lhz, "lhzu", Iload},
+[42] {lha, "lha", Iload},
+[43] {lha, "lhau", Iload},
+[44] {sth, "sth", Istore},
+[45] {sth, "sthu", Istore},
+[46] {lmw, "lmw", Iload},
+[47] {stmw, "stmw", Istore},
+[48] {lfs, "lfs", Iload},
+[49] {lfs, "lfsu", Iload},
+[50] {lfd, "lfd", Iload},
+[51] {lfd, "lfdu", Iload},
+[52] {stfs, "stfs", Istore},
+[53] {stfs, "stfsu", Istore},
+[54] {stfd, "stfd", Istore},
+[55] {stfd, "stfdu", Istore},
+/* group 59; single precision floating point */
+/* group 63; double precision floating point; fpscr */
+ {0, 0, 0},
+};
+
+Inset ops0 = {op0, nelem(op0)-1};
+
+static char oemflag[] = {
+ [104] 1,
+ [10] 1,
+ [136] 1,
+ [138] 1,
+ [200] 1,
+ [202] 1,
+ [232] 1,
+ [234] 1,
+ [235] 1,
+ [266] 1,
+ [40] 1,
+ [459] 1,
+ [491] 1,
+ [8] 1,
+};
+
+
+void
+run(void)
+{
+ int xo, f;
+
+ do {
+ reg.ir = ifetch(reg.pc);
+ ci = 0;
+ switch(reg.ir>>26) {
+ default:
+ xo = reg.ir>>26;
+ if(xo >= nelem(op0))
+ break;
+ ci = &op0[xo];
+ break;
+ case 19:
+ xo = getxo(reg.ir);
+ if(xo >= ops19.nel)
+ break;
+ ci = &ops19.tab[xo];
+ break;
+ case 31:
+ xo = getxo(reg.ir);
+ f = xo & ~getxo(OE);
+ if(reg.ir&OE && f < sizeof(oemflag) && oemflag[f])
+ xo = f;
+ if(xo >= ops31.nel)
+ break;
+ ci = &ops31.tab[xo];
+ break;
+ case 59:
+ xo = getxo(reg.ir) & 0x1F;
+ if(xo >= ops59.nel)
+ break;
+ ci = &ops59.tab[xo];
+ break;
+ case 63:
+ xo = getxo(reg.ir) & 0x1F;
+ if(xo < ops63a.nel) {
+ ci = &ops63a.tab[xo];
+ if(ci->func || ci->name)
+ break;
+ ci = 0;
+ }
+ xo = getxo(reg.ir);
+ if(xo >= ops63b.nel)
+ break;
+ ci = &ops63b.tab[xo];
+ break;
+ }
+ if(ci && ci->func){
+ ci->count++;
+ (*ci->func)(reg.ir);
+ } else {
+ if(ci && ci->name && trace)
+ itrace("%s\t[not yet done]", ci->name);
+ else
+ undef(reg.ir);
+ }
+ reg.pc += 4;
+ if(bplist)
+ brkchk(reg.pc, Instruction);
+ }while(--count);
+}
+
+void
+ilock(int)
+{
+}
+
+void
+undef(ulong ir)
+{
+/* Bprint(bioout, "op=%d op2=%d op3=%d\n", ir>>30, (ir>>21)&0x7, (ir>>19)&0x3f); */
+ Bprint(bioout, "illegal_instruction IR #%.8lux (op=%ld/%ld, pc=#%.8lux)\n", ir, getop(ir), getxo(ir), reg.pc);
+ if(ci && ci->name && ci->func==0)
+ Bprint(bioout, "(%s not yet implemented)\n", ci->name);
+ longjmp(errjmp, 0);
+}
+
+void
+unimp(ulong ir)
+{
+/* Bprint(bioout, "op=%d op2=%d op3=%d\n", ir>>30, (ir>>21)&0x7, (ir>>19)&0x3f); */
+ Bprint(bioout, "illegal_instruction IR #%.8lux (op=%ld/%ld, pc=#%.8lux) %s not in MPC601\n", ir, getop(ir), getxo(ir), reg.pc, ci->name?ci->name: "-");
+ longjmp(errjmp, 0);
+}