sewardj | b17322f | 2013-04-11 10:58:18 +0000 | [diff] [blame] | 1 | |
| 2 | // This should be compiled as Thumb code, since currently V only |
sewardj | 56c2e87 | 2013-05-13 10:29:32 +0000 | [diff] [blame] | 3 | // handles the T1 encoding of ldrt. This all assumes that we are |
| 4 | // in a little-endian world. |
sewardj | b17322f | 2013-04-11 10:58:18 +0000 | [diff] [blame] | 5 | |
| 6 | #include <stdio.h> |
| 7 | #include <malloc.h> |
| 8 | |
| 9 | typedef unsigned int UInt; |
| 10 | |
| 11 | __attribute__((noinline)) UInt do_ldrt_imm_132 ( unsigned char* p ) |
| 12 | { |
| 13 | UInt res; |
| 14 | __asm__ __volatile__( |
| 15 | "mov r5, %1 ; ldrt r6, [r5, #132] ; mov %0, r6" |
| 16 | : "=r"(res) : "r"(p) : "r5", "r6" |
| 17 | ); |
| 18 | return res; |
| 19 | } |
| 20 | |
sewardj | 56c2e87 | 2013-05-13 10:29:32 +0000 | [diff] [blame] | 21 | __attribute__((noinline)) void do_strt_imm_132 ( unsigned char* p, UInt val ) |
| 22 | { |
| 23 | __asm__ __volatile__( |
| 24 | "mov r5, %0 ; mov r6, %1 ; strt r6, [r5, #132]" |
| 25 | : : "r"(p), "r"(val) : "r5", "r6", "memory" |
| 26 | ); |
| 27 | } |
| 28 | |
sewardj | 7d75870 | 2013-07-04 15:29:07 +0000 | [diff] [blame] | 29 | __attribute__((noinline)) void do_strbt_imm_132 ( unsigned char* p, UInt* val ) |
| 30 | { |
| 31 | __asm__ __volatile__( |
| 32 | "mov r5, %0 ; ldr r6, [r5] ; mov r5, %1; strbt r6, [r5, #132]" |
| 33 | : : "r"(val), "r"(p) : "r5", "r6", "memory" |
| 34 | ); |
| 35 | } |
| 36 | |
sewardj | 333ff44 | 2013-09-29 18:25:29 +0000 | [diff] [blame] | 37 | __attribute__((noinline)) UInt do_ldrht_imm_1 (unsigned char* val) |
| 38 | { |
| 39 | UInt res; |
| 40 | __asm__ __volatile__( |
| 41 | "mov r4, %1 ; ldrht r5, [r4, #1]; mov %0, r5" |
| 42 | : "=r"(res) : "r"(val) : "r4", "r5" |
| 43 | ); |
| 44 | return res; |
| 45 | } |
| 46 | |
| 47 | __attribute__((noinline)) void do_ldrsht_imm_1 (UInt* res) |
| 48 | { |
| 49 | __asm__ __volatile__( |
| 50 | "mov r4, %1 ; ldrsht r5, [r4, #1] ; str r5, [r4, #0]" |
| 51 | : "+r"(res) : : "r4", "r5", "memory" |
| 52 | ); |
| 53 | } |
| 54 | |
sewardj | 7d75870 | 2013-07-04 15:29:07 +0000 | [diff] [blame] | 55 | __attribute__((noinline)) void do_strht_imm_132 ( unsigned char* p, UInt* val ) |
| 56 | { |
| 57 | __asm__ __volatile__( |
| 58 | "mov r5, %0 ; ldr r6, [r5] ; mov r5, %1; strht r6, [r5, #132]" |
| 59 | : : "r"(val), "r"(p) : "r5", "r6", "memory" |
| 60 | ); |
| 61 | } |
| 62 | |
| 63 | __attribute__((noinline)) UInt do_ldrbt_imm_2 (unsigned char* val) |
| 64 | { |
| 65 | UInt res; |
| 66 | __asm__ __volatile__( |
| 67 | "mov r4, %1 ; ldrbt r5, [r4, #2]; mov %0, r5" |
| 68 | : "=r"(res) : "r"(val) : "r4", "r5" |
| 69 | ); |
| 70 | return res; |
| 71 | } |
| 72 | |
| 73 | __attribute__((noinline)) UInt do_ldrsbt_imm_2 (unsigned char* val) |
| 74 | { |
| 75 | UInt res; |
| 76 | __asm__ __volatile__( |
| 77 | "mov r4, %1 ; ldrsbt r5, [r4, #2]; mov %0, r5" |
| 78 | : "=r"(res) : "r"(val) : "r4", "r5" |
| 79 | ); |
| 80 | return res; |
| 81 | } |
| 82 | |
sewardj | b17322f | 2013-04-11 10:58:18 +0000 | [diff] [blame] | 83 | int main ( void ) |
| 84 | { |
| 85 | UInt i; |
| 86 | unsigned char* b = malloc(256); |
| 87 | for (i = 0; i < 256; i++) b[i] = (unsigned char)i; |
| 88 | UInt r = do_ldrt_imm_132(b); |
| 89 | free(b); |
| 90 | printf("result is 0x%08x (should be 0x%08x)\n", r, 0x87868584); |
sewardj | 56c2e87 | 2013-05-13 10:29:32 +0000 | [diff] [blame] | 91 | |
| 92 | UInt val = (200 << 0) | (150 << 8) | (100 << 16) | (10 << 24); |
| 93 | unsigned char* c = malloc(256); |
| 94 | for (i = 0; i < 256; i++) c[i] = (unsigned char)i; |
| 95 | do_strt_imm_132(c, val); |
| 96 | printf("result is %u %u %u %u %u %u (should be %u %u %u %u %u %u)\n", |
| 97 | c[131], c[132], c[133], c[134], c[135], c[136], |
| 98 | 131, 200, 150, 100, 10, 136); |
| 99 | free(c); |
sewardj | 7d75870 | 2013-07-04 15:29:07 +0000 | [diff] [blame] | 100 | |
| 101 | UInt val_bt = 0b11111111; |
| 102 | unsigned char* d = malloc(256); |
| 103 | for (i = 0; i < 256; i++) d[i] = (unsigned char)i; |
| 104 | do_strbt_imm_132(d, &val_bt); |
| 105 | printf("result is %u %u %u (should be %u %u %u)\n", |
| 106 | d[131], d[132], d[133], 131, 255, 133); |
| 107 | free(d); |
| 108 | |
| 109 | UInt val_ht = 0xFFFF; |
| 110 | unsigned char* e = malloc(256); |
| 111 | for (i = 0; i < 256; i++) e[i] = (unsigned char)i; |
| 112 | do_strht_imm_132(e, &val_ht); |
| 113 | printf("result is %u %u %u %u (should be %u %u %u %u)\n", |
| 114 | e[131], e[132], e[133], e[134], 131, 255, 255, 134); |
| 115 | free(e); |
| 116 | |
| 117 | UInt val_ldrbt = (200 << 0) | (150 << 8) | (137 << 16) | (10 << 24); |
| 118 | printf("result is %u (should be %u)\n", |
| 119 | do_ldrbt_imm_2((unsigned char*)&val_ldrbt), 137); |
| 120 | |
| 121 | UInt val_ldrsbt = (200 << 0) | (150 << 8) | (254 << 16) | (10 << 24); |
sewardj | 84a646e | 2013-08-15 21:18:21 +0000 | [diff] [blame] | 122 | printf("result is %u (should be %llu)\n", |
| 123 | do_ldrsbt_imm_2((unsigned char*)&val_ldrsbt), 4294967294ULL); |
sewardj | 7d75870 | 2013-07-04 15:29:07 +0000 | [diff] [blame] | 124 | |
sewardj | 333ff44 | 2013-09-29 18:25:29 +0000 | [diff] [blame] | 125 | |
| 126 | UInt val_ldrht = 0xABFEFD8D; |
| 127 | printf("result is %u (should be %u)\n", |
| 128 | do_ldrht_imm_1((unsigned char*)(&val_ldrht)), 65277); |
| 129 | |
| 130 | UInt val_ldrsht = 0x00BADFAA; |
| 131 | do_ldrsht_imm_1(&val_ldrsht); |
| 132 | printf("result is 0x%x (should be 0x%x)\n", val_ldrsht, 0xFFFFBADF); |
| 133 | |
sewardj | b17322f | 2013-04-11 10:58:18 +0000 | [diff] [blame] | 134 | return 0; |
| 135 | } |