fix bigint shift tests
[openpower-isa.git] / jit_test.cpp
1 typedef __UINT8_TYPE__ uint8_t;
2 typedef __UINT16_TYPE__ uint16_t;
3 typedef __UINT32_TYPE__ uint32_t;
4 typedef __UINT64_TYPE__ uint64_t;
5 typedef __INT8_TYPE__ int8_t;
6 typedef __INT16_TYPE__ int16_t;
7 typedef __INT32_TYPE__ int32_t;
8 typedef __INT64_TYPE__ int64_t;
9
10 /// returns `v + inc` by jitting an addi instruction and executing it
11 /// requires .wtext section to be writable
12 extern "C" uint64_t jit_test(uint64_t v, int16_t inc) __attribute__((noinline, section(".wtext")));
13 extern "C" uint64_t jit_test(uint64_t v, int16_t inc) {
14 register uint64_t r3 asm("r3");
15 r3 = v;
16 uint32_t instr = 0x38630000 | (uint16_t)inc; // addi 3, 3, inc
17 asm("mflr 5\n\t"
18 "bl 0f\n\t"
19 "0: mflr 4\n\t"
20 "addi 4, 4, 1f - 0b\n\t"
21 "stw %1, 0(4)\n\t"
22 "dcbf 0, 4\n\t"
23 "sync\n\t"
24 "icbi 0, 4\n\t"
25 "isync\n\t"
26 "1: addi 3, 3, 0x1234\n\t"
27 "mtlr 5"
28 : "+b"(r3) : "b"(instr) : "r4", "r5");
29 return r3;
30 }
31
32 extern "C" uint64_t parse_hex(const char *s) __attribute__((noinline));
33 extern "C" uint64_t parse_hex(const char *s) {
34 uint64_t retval = 0;
35 bool negate = *s == '-';
36 if(*s == '-' || *s == '+')
37 s++;
38 if(*s == '0' && (s[1] == 'x' || s[1] == 'X'))
39 s += 2;
40 if(!*s)
41 return -1;
42 for(; *s; s++) {
43 uint64_t digit;
44 if(*s >= '0' && *s <= '9')
45 digit = *s - '0';
46 else if(*s >= 'a' && *s <= 'f')
47 digit = *s - 'a' + 0xA;
48 else if(*s >= 'A' && *s <= 'F')
49 digit = *s - 'A' + 0xA;
50 else
51 return -1;
52 if(retval >= 1ULL << 60)
53 return -1;
54 retval <<= 4;
55 retval += digit;
56 }
57 return retval;
58 }
59
60 extern "C" int main(int argc, char **argv) {
61 uint64_t a = 1, b = 2;
62 if(argc > 1)
63 a = parse_hex(argv[1]);
64 if(argc > 2)
65 b = parse_hex(argv[2]);
66 register long r3 asm("r3") = jit_test(a, b);
67 register long r0 asm("r0") = 1; // exit
68 asm volatile("sc" : : "r"(r0), "b"(r3));
69 }