| #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; |
| } |