Home | History | Annotate | Download | only in arm
      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