summaryrefslogtreecommitdiff
path: root/rts/Disassembler.c
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2011-11-02 10:19:51 +0000
committerSimon Marlow <marlowsd@gmail.com>2011-11-02 16:34:06 +0000
commit78eadcca1306a2fcb22adfb02f9da460bcd5b7cc (patch)
tree9c108f844eb69e7b3a29ac796f06a1b799041b18 /rts/Disassembler.c
parentf6fb053ffd072d8d04fb9f2ab47eb1c9022f479e (diff)
downloadhaskell-78eadcca1306a2fcb22adfb02f9da460bcd5b7cc.tar.gz
fix disassembling of large instructions
Diffstat (limited to 'rts/Disassembler.c')
-rw-r--r--rts/Disassembler.c44
1 files changed, 36 insertions, 8 deletions
diff --git a/rts/Disassembler.c b/rts/Disassembler.c
index fff3fe9d76..d043e1d012 100644
--- a/rts/Disassembler.c
+++ b/rts/Disassembler.c
@@ -40,7 +40,31 @@ disInstr ( StgBCO *bco, int pc )
StgPtr* ptrs = (StgPtr*)(&ptrs_arr->payload[0]);
instr = instrs[pc++];
- switch (instr) {
+ if (instr & bci_FLAG_LARGE_ARGS) {
+ debugBelch ("LARGE ");
+ }
+
+#define BCO_NEXT instrs[pc++]
+#define BCO_NEXT_32 (pc += 2)
+#define BCO_READ_NEXT_32 (BCO_NEXT_32, (((StgWord) instrs[pc-2]) << 16) \
+ + ( (StgWord) instrs[pc-1]))
+#define BCO_NEXT_64 (pc += 4)
+#define BCO_READ_NEXT_64 (BCO_NEXT_64, (((StgWord) instrs[pc-4]) << 48) \
+ + (((StgWord) instrs[pc-3]) << 32) \
+ + (((StgWord) instrs[pc-2]) << 16) \
+ + ( (StgWord) instrs[pc-1]))
+#if WORD_SIZE_IN_BITS == 32
+#define BCO_NEXT_WORD BCO_NEXT_32
+#define BCO_READ_NEXT_WORD BCO_READ_NEXT_32
+#elif WORD_SIZE_IN_BITS == 64
+#define BCO_NEXT_WORD BCO_NEXT_64
+#define BCO_READ_NEXT_WORD BCO_READ_NEXT_64
+#else
+#error Cannot cope with WORD_SIZE_IN_BITS being nether 32 nor 64
+#endif
+#define BCO_GET_LARGE_ARG ((instr & bci_FLAG_LARGE_ARGS) ? BCO_READ_NEXT_WORD : BCO_NEXT)
+
+ switch (instr & 0xff) {
case bci_BRK_FUN:
debugBelch ("BRK_FUN " ); printPtr( ptrs[instrs[pc]] );
debugBelch (" %d ", instrs[pc+1]); printPtr( ptrs[instrs[pc+2]] ); debugBelch("\n" );
@@ -54,9 +78,11 @@ disInstr ( StgBCO *bco, int pc )
debugBelch("CCALL marshaller at 0x%lx\n",
literals[instrs[pc]] );
pc += 1; break;
- case bci_STKCHECK:
- debugBelch("STKCHECK %d\n", instrs[pc] );
- pc += 1; break;
+ case bci_STKCHECK: {
+ StgWord stk_words_reqd = BCO_GET_LARGE_ARG + 1;
+ debugBelch("STKCHECK %lu\n", (lnat)stk_words_reqd );
+ break;
+ }
case bci_PUSH_L:
debugBelch("PUSH_L %d\n", instrs[pc] );
pc += 1; break;
@@ -170,10 +196,12 @@ disInstr ( StgBCO *bco, int pc )
debugBelch("\n");
pc += 2; break;
- case bci_TESTLT_I:
- debugBelch("TESTLT_I %ld, fail to %d\n", literals[instrs[pc]],
- instrs[pc+1]);
- pc += 2; break;
+ case bci_TESTLT_I: {
+ unsigned int discr = BCO_NEXT;
+ int failto = BCO_GET_LARGE_ARG;
+ debugBelch("TESTLT_I %ld, fail to %d\n", literals[discr], failto);
+ break;
+ }
case bci_TESTEQ_I:
debugBelch("TESTEQ_I %ld, fail to %d\n", literals[instrs[pc]],
instrs[pc+1]);