1 2 // This should be compiled as Thumb code, since currently V only 3 // handles the T1 encoding of ldrt. This all assumes that we are 4 // in a little-endian world. 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 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 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 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 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 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); 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); 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); 122 printf("result is %u (should be %llu)\n", 123 do_ldrsbt_imm_2((unsigned char*)&val_ldrsbt), 4294967294ULL); 124 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 134 return 0; 135 } 136