mirror of
https://github.com/ioacademy-jikim/debugging
synced 2025-06-18 13:26:14 +00:00
130 lines
3.6 KiB
C
130 lines
3.6 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "opcodes.h"
|
|
|
|
#define LOAD_REG_MEM(insn, s, ccset, initial, mask) \
|
|
({ \
|
|
register unsigned long target asm("1") = initial; \
|
|
unsigned long source = s; \
|
|
register unsigned long *addr asm("5") = &source; \
|
|
unsigned int a,b; \
|
|
switch(ccset) { \
|
|
case 0: a = 0; b = 0; break; \
|
|
case 1: a = 1; b = 0; break; \
|
|
case 2: a = 0xffffffff; b = 1; break; \
|
|
case 3: a = 0xffffffff; b = 2; break; \
|
|
default: abort(); \
|
|
} \
|
|
asm volatile( "alr %1, %3\n" /* set cc */ \
|
|
insn(1,mask,5,000,00) \
|
|
: "+d" (target), "+d" (a) \
|
|
: "Q" (source), "d" (b), "d"(addr) \
|
|
: "cc"); \
|
|
printf(#insn " %16.16lX into %16.16lX if mask" \
|
|
"%d for cc %d: %16.16lX\n",s, initial, \
|
|
0x##mask, ccset, target); \
|
|
})
|
|
|
|
|
|
#define LOAD_REG_REG(insn, s, ccset, initial, mask) \
|
|
({ \
|
|
register unsigned long target asm("1") = initial; \
|
|
register unsigned long source asm("2")= s; \
|
|
unsigned int a,b; \
|
|
switch(ccset) { \
|
|
case 0: a = 0; b = 0; break; \
|
|
case 1: a = 1; b = 0; break; \
|
|
case 2: a = 0xffffffff; b = 1; break; \
|
|
case 3: a = 0xffffffff; b = 2; break; \
|
|
default: abort(); \
|
|
} \
|
|
asm volatile( "alr %1, %3\n" /* set cc */ \
|
|
insn(mask,1,2) \
|
|
: "+d" (target), "+d" (a) \
|
|
: "d" (source), "d" (b) \
|
|
: "cc"); \
|
|
printf(#insn " %16.16lX into %16.16lX if mask" \
|
|
"%d for cc %d: %16.16lX\n",s, initial, \
|
|
0x##mask, ccset, target); \
|
|
})
|
|
|
|
#define STORE_REG_REG(insn, s, ccset, initial, mask) \
|
|
({ \
|
|
unsigned long target = initial; \
|
|
register unsigned long source asm("1") = s; \
|
|
register unsigned long *addr asm("5") = ⌖ \
|
|
unsigned int a,b; \
|
|
switch(ccset) { \
|
|
case 0: a = 0; b = 0; break; \
|
|
case 1: a = 1; b = 0; break; \
|
|
case 2: a = 0xffffffff; b = 1; break; \
|
|
case 3: a = 0xffffffff; b = 2; break; \
|
|
default: abort(); \
|
|
} \
|
|
asm volatile( "alr %1, %3\n" /* set cc */ \
|
|
insn(1,mask,5,000,00) \
|
|
: "+Q" (target), "+d" (a) \
|
|
: "d" (source), "d" (b), "d"(addr) \
|
|
: "cc"); \
|
|
printf(#insn " %16.16lX into %16.16lX if mask" \
|
|
"%d for cc %d: %16.16lX\n",s, initial, \
|
|
0x##mask, ccset, target); \
|
|
})
|
|
|
|
|
|
#define INSNVALCCINIT(insn, value, ccset, INIT, FUNC) \
|
|
({ \
|
|
FUNC(insn, value, ccset, INIT, 0); \
|
|
FUNC(insn, value, ccset, INIT, 1); \
|
|
FUNC(insn, value, ccset, INIT, 2); \
|
|
FUNC(insn, value, ccset, INIT, 3); \
|
|
FUNC(insn, value, ccset, INIT, 4); \
|
|
FUNC(insn, value, ccset, INIT, 5); \
|
|
FUNC(insn, value, ccset, INIT, 6); \
|
|
FUNC(insn, value, ccset, INIT, 7); \
|
|
FUNC(insn, value, ccset, INIT, 8); \
|
|
FUNC(insn, value, ccset, INIT, 9); \
|
|
FUNC(insn, value, ccset, INIT, A); \
|
|
FUNC(insn, value, ccset, INIT, B); \
|
|
FUNC(insn, value, ccset, INIT, C); \
|
|
FUNC(insn, value, ccset, INIT, D); \
|
|
FUNC(insn, value, ccset, INIT, E); \
|
|
FUNC(insn, value, ccset, INIT, F); \
|
|
})
|
|
|
|
|
|
|
|
|
|
#define INSNVALCC(insn, value, ccset, FUNC) \
|
|
({ \
|
|
INSNVALCCINIT(insn, value, ccset, 0UL, FUNC); \
|
|
INSNVALCCINIT(insn, value, ccset, 0xffffffffffffffffUL, FUNC); \
|
|
})
|
|
|
|
#define INSNVAL(insn, value, FUNC) \
|
|
({ \
|
|
INSNVALCC(insn, value, 0, FUNC); \
|
|
INSNVALCC(insn, value, 1, FUNC); \
|
|
INSNVALCC(insn, value, 2, FUNC); \
|
|
INSNVALCC(insn, value, 3, FUNC); \
|
|
})
|
|
|
|
#define DO_INSN(insn, FUNC) \
|
|
({ \
|
|
INSNVAL(insn, 0UL, FUNC); \
|
|
INSNVAL(insn, 0xffffffffUL, FUNC); \
|
|
INSNVAL(insn, 0xffffffffffffffffUL, FUNC); \
|
|
INSNVAL(insn, 0xffffffff00000000UL, FUNC); \
|
|
})
|
|
|
|
int main()
|
|
{
|
|
DO_INSN(LOC, LOAD_REG_MEM);
|
|
DO_INSN(LOCG, LOAD_REG_MEM);
|
|
DO_INSN(LOCR, LOAD_REG_REG);
|
|
DO_INSN(LOCGR, LOAD_REG_REG);
|
|
DO_INSN(STOC, STORE_REG_REG);
|
|
DO_INSN(STOCG, STORE_REG_REG);
|
|
return 0;
|
|
}
|