Annotation of qemu/target-arm/op.c, revision 1.1.1.3

1.1       root        1: /*
                      2:  *  ARM micro operations
                      3:  * 
                      4:  *  Copyright (c) 2003 Fabrice Bellard
                      5:  *  Copyright (c) 2005 CodeSourcery, LLC
                      6:  *
                      7:  * This library is free software; you can redistribute it and/or
                      8:  * modify it under the terms of the GNU Lesser General Public
                      9:  * License as published by the Free Software Foundation; either
                     10:  * version 2 of the License, or (at your option) any later version.
                     11:  *
                     12:  * This library is distributed in the hope that it will be useful,
                     13:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     15:  * Lesser General Public License for more details.
                     16:  *
                     17:  * You should have received a copy of the GNU Lesser General Public
                     18:  * License along with this library; if not, write to the Free Software
                     19:  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     20:  */
                     21: #include "exec.h"
                     22: 
                     23: #define REGNAME r0
                     24: #define REG (env->regs[0])
                     25: #include "op_template.h"
                     26: 
                     27: #define REGNAME r1
                     28: #define REG (env->regs[1])
                     29: #include "op_template.h"
                     30: 
                     31: #define REGNAME r2
                     32: #define REG (env->regs[2])
                     33: #include "op_template.h"
                     34: 
                     35: #define REGNAME r3
                     36: #define REG (env->regs[3])
                     37: #include "op_template.h"
                     38: 
                     39: #define REGNAME r4
                     40: #define REG (env->regs[4])
                     41: #include "op_template.h"
                     42: 
                     43: #define REGNAME r5
                     44: #define REG (env->regs[5])
                     45: #include "op_template.h"
                     46: 
                     47: #define REGNAME r6
                     48: #define REG (env->regs[6])
                     49: #include "op_template.h"
                     50: 
                     51: #define REGNAME r7
                     52: #define REG (env->regs[7])
                     53: #include "op_template.h"
                     54: 
                     55: #define REGNAME r8
                     56: #define REG (env->regs[8])
                     57: #include "op_template.h"
                     58: 
                     59: #define REGNAME r9
                     60: #define REG (env->regs[9])
                     61: #include "op_template.h"
                     62: 
                     63: #define REGNAME r10
                     64: #define REG (env->regs[10])
                     65: #include "op_template.h"
                     66: 
                     67: #define REGNAME r11
                     68: #define REG (env->regs[11])
                     69: #include "op_template.h"
                     70: 
                     71: #define REGNAME r12
                     72: #define REG (env->regs[12])
                     73: #include "op_template.h"
                     74: 
                     75: #define REGNAME r13
                     76: #define REG (env->regs[13])
                     77: #include "op_template.h"
                     78: 
                     79: #define REGNAME r14
                     80: #define REG (env->regs[14])
                     81: #include "op_template.h"
                     82: 
                     83: #define REGNAME r15
                     84: #define REG (env->regs[15])
                     85: #define SET_REG(x) REG = x & ~(uint32_t)1
                     86: #include "op_template.h"
                     87: 
                     88: void OPPROTO op_bx_T0(void)
                     89: {
                     90:   env->regs[15] = T0 & ~(uint32_t)1;
                     91:   env->thumb = (T0 & 1) != 0;
                     92: }
                     93: 
                     94: void OPPROTO op_movl_T0_0(void)
                     95: {
                     96:     T0 = 0;
                     97: }
                     98: 
                     99: void OPPROTO op_movl_T0_im(void)
                    100: {
                    101:     T0 = PARAM1;
                    102: }
                    103: 
1.1.1.2   root      104: void OPPROTO op_movl_T0_T1(void)
                    105: {
                    106:     T0 = T1;
                    107: }
                    108: 
1.1       root      109: void OPPROTO op_movl_T1_im(void)
                    110: {
                    111:     T1 = PARAM1;
                    112: }
                    113: 
                    114: void OPPROTO op_mov_CF_T1(void)
                    115: {
                    116:     env->CF = ((uint32_t)T1) >> 31;
                    117: }
                    118: 
                    119: void OPPROTO op_movl_T2_im(void)
                    120: {
                    121:     T2 = PARAM1;
                    122: }
                    123: 
                    124: void OPPROTO op_addl_T1_im(void)
                    125: {
                    126:     T1 += PARAM1;
                    127: }
                    128: 
                    129: void OPPROTO op_addl_T1_T2(void)
                    130: {
                    131:     T1 += T2;
                    132: }
                    133: 
                    134: void OPPROTO op_subl_T1_T2(void)
                    135: {
                    136:     T1 -= T2;
                    137: }
                    138: 
                    139: void OPPROTO op_addl_T0_T1(void)
                    140: {
                    141:     T0 += T1;
                    142: }
                    143: 
                    144: void OPPROTO op_addl_T0_T1_cc(void)
                    145: {
                    146:     unsigned int src1;
                    147:     src1 = T0;
                    148:     T0 += T1;
                    149:     env->NZF = T0;
                    150:     env->CF = T0 < src1;
                    151:     env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0);
                    152: }
                    153: 
                    154: void OPPROTO op_adcl_T0_T1(void)
                    155: {
                    156:     T0 += T1 + env->CF;
                    157: }
                    158: 
                    159: void OPPROTO op_adcl_T0_T1_cc(void)
                    160: {
                    161:     unsigned int src1;
                    162:     src1 = T0;
                    163:     if (!env->CF) {
                    164:         T0 += T1;
                    165:         env->CF = T0 < src1;
                    166:     } else {
                    167:         T0 += T1 + 1;
                    168:         env->CF = T0 <= src1;
                    169:     }
                    170:     env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0);
                    171:     env->NZF = T0;
                    172:     FORCE_RET();
                    173: }
                    174: 
                    175: #define OPSUB(sub, sbc, res, T0, T1)            \
                    176:                                                 \
                    177: void OPPROTO op_ ## sub ## l_T0_T1(void)        \
                    178: {                                               \
                    179:     res = T0 - T1;                              \
                    180: }                                               \
                    181:                                                 \
                    182: void OPPROTO op_ ## sub ## l_T0_T1_cc(void)     \
                    183: {                                               \
                    184:     unsigned int src1;                          \
                    185:     src1 = T0;                                  \
                    186:     T0 -= T1;                                   \
                    187:     env->NZF = T0;                              \
                    188:     env->CF = src1 >= T1;                       \
                    189:     env->VF = (src1 ^ T1) & (src1 ^ T0);        \
                    190:     res = T0;                                   \
                    191: }                                               \
                    192:                                                 \
                    193: void OPPROTO op_ ## sbc ## l_T0_T1(void)        \
                    194: {                                               \
                    195:     res = T0 - T1 + env->CF - 1;                \
                    196: }                                               \
                    197:                                                 \
                    198: void OPPROTO op_ ## sbc ## l_T0_T1_cc(void)     \
                    199: {                                               \
                    200:     unsigned int src1;                          \
                    201:     src1 = T0;                                  \
                    202:     if (!env->CF) {                             \
                    203:         T0 = T0 - T1 - 1;                       \
                    204:         env->CF = src1 > T1;                    \
                    205:     } else {                                    \
                    206:         T0 = T0 - T1;                           \
                    207:         env->CF = src1 >= T1;                   \
                    208:     }                                           \
                    209:     env->VF = (src1 ^ T1) & (src1 ^ T0);        \
                    210:     env->NZF = T0;                              \
                    211:     res = T0;                                   \
                    212:     FORCE_RET();                                \
                    213: }
                    214: 
                    215: OPSUB(sub, sbc, T0, T0, T1)
                    216: 
                    217: OPSUB(rsb, rsc, T0, T1, T0)
                    218: 
                    219: void OPPROTO op_andl_T0_T1(void)
                    220: {
                    221:     T0 &= T1;
                    222: }
                    223: 
                    224: void OPPROTO op_xorl_T0_T1(void)
                    225: {
                    226:     T0 ^= T1;
                    227: }
                    228: 
                    229: void OPPROTO op_orl_T0_T1(void)
                    230: {
                    231:     T0 |= T1;
                    232: }
                    233: 
                    234: void OPPROTO op_bicl_T0_T1(void)
                    235: {
                    236:     T0 &= ~T1;
                    237: }
                    238: 
                    239: void OPPROTO op_notl_T1(void)
                    240: {
                    241:     T1 = ~T1;
                    242: }
                    243: 
                    244: void OPPROTO op_logic_T0_cc(void)
                    245: {
                    246:     env->NZF = T0;
                    247: }
                    248: 
                    249: void OPPROTO op_logic_T1_cc(void)
                    250: {
                    251:     env->NZF = T1;
                    252: }
                    253: 
                    254: #define EIP (env->regs[15])
                    255: 
                    256: void OPPROTO op_test_eq(void)
                    257: {
                    258:     if (env->NZF == 0)
                    259:         GOTO_LABEL_PARAM(1);;
                    260:     FORCE_RET();
                    261: }
                    262: 
                    263: void OPPROTO op_test_ne(void)
                    264: {
                    265:     if (env->NZF != 0)
                    266:         GOTO_LABEL_PARAM(1);;
                    267:     FORCE_RET();
                    268: }
                    269: 
                    270: void OPPROTO op_test_cs(void)
                    271: {
                    272:     if (env->CF != 0)
                    273:         GOTO_LABEL_PARAM(1);
                    274:     FORCE_RET();
                    275: }
                    276: 
                    277: void OPPROTO op_test_cc(void)
                    278: {
                    279:     if (env->CF == 0)
                    280:         GOTO_LABEL_PARAM(1);
                    281:     FORCE_RET();
                    282: }
                    283: 
                    284: void OPPROTO op_test_mi(void)
                    285: {
                    286:     if ((env->NZF & 0x80000000) != 0)
                    287:         GOTO_LABEL_PARAM(1);
                    288:     FORCE_RET();
                    289: }
                    290: 
                    291: void OPPROTO op_test_pl(void)
                    292: {
                    293:     if ((env->NZF & 0x80000000) == 0)
                    294:         GOTO_LABEL_PARAM(1);
                    295:     FORCE_RET();
                    296: }
                    297: 
                    298: void OPPROTO op_test_vs(void)
                    299: {
                    300:     if ((env->VF & 0x80000000) != 0)
                    301:         GOTO_LABEL_PARAM(1);
                    302:     FORCE_RET();
                    303: }
                    304: 
                    305: void OPPROTO op_test_vc(void)
                    306: {
                    307:     if ((env->VF & 0x80000000) == 0)
                    308:         GOTO_LABEL_PARAM(1);
                    309:     FORCE_RET();
                    310: }
                    311: 
                    312: void OPPROTO op_test_hi(void)
                    313: {
                    314:     if (env->CF != 0 && env->NZF != 0)
                    315:         GOTO_LABEL_PARAM(1);
                    316:     FORCE_RET();
                    317: }
                    318: 
                    319: void OPPROTO op_test_ls(void)
                    320: {
                    321:     if (env->CF == 0 || env->NZF == 0)
                    322:         GOTO_LABEL_PARAM(1);
                    323:     FORCE_RET();
                    324: }
                    325: 
                    326: void OPPROTO op_test_ge(void)
                    327: {
                    328:     if (((env->VF ^ env->NZF) & 0x80000000) == 0)
                    329:         GOTO_LABEL_PARAM(1);
                    330:     FORCE_RET();
                    331: }
                    332: 
                    333: void OPPROTO op_test_lt(void)
                    334: {
                    335:     if (((env->VF ^ env->NZF) & 0x80000000) != 0)
                    336:         GOTO_LABEL_PARAM(1);
                    337:     FORCE_RET();
                    338: }
                    339: 
                    340: void OPPROTO op_test_gt(void)
                    341: {
                    342:     if (env->NZF != 0 && ((env->VF ^ env->NZF) & 0x80000000) == 0)
                    343:         GOTO_LABEL_PARAM(1);
                    344:     FORCE_RET();
                    345: }
                    346: 
                    347: void OPPROTO op_test_le(void)
                    348: {
                    349:     if (env->NZF == 0 || ((env->VF ^ env->NZF) & 0x80000000) != 0)
                    350:         GOTO_LABEL_PARAM(1);
                    351:     FORCE_RET();
                    352: }
                    353: 
1.1.1.2   root      354: void OPPROTO op_goto_tb0(void)
1.1       root      355: {
1.1.1.2   root      356:     GOTO_TB(op_goto_tb0, PARAM1, 0);
1.1       root      357: }
                    358: 
1.1.1.2   root      359: void OPPROTO op_goto_tb1(void)
1.1       root      360: {
1.1.1.2   root      361:     GOTO_TB(op_goto_tb1, PARAM1, 1);
1.1       root      362: }
                    363: 
                    364: void OPPROTO op_exit_tb(void)
                    365: {
                    366:     EXIT_TB();
                    367: }
                    368: 
1.1.1.2   root      369: void OPPROTO op_movl_T0_cpsr(void)
                    370: {
                    371:     T0 = cpsr_read(env);
                    372:     FORCE_RET();
                    373: }
                    374: 
                    375: void OPPROTO op_movl_T0_spsr(void)
                    376: {
                    377:     T0 = env->spsr;
                    378: }
                    379: 
                    380: void OPPROTO op_movl_spsr_T0(void)
1.1       root      381: {
1.1.1.2   root      382:     uint32_t mask = PARAM1;
                    383:     env->spsr = (env->spsr & ~mask) | (T0 & mask);
1.1       root      384: }
                    385: 
1.1.1.2   root      386: void OPPROTO op_movl_cpsr_T0(void)
1.1       root      387: {
1.1.1.2   root      388:     cpsr_write(env, T0, PARAM1);
                    389:     FORCE_RET();
1.1       root      390: }
                    391: 
                    392: void OPPROTO op_mul_T0_T1(void)
                    393: {
                    394:     T0 = T0 * T1;
                    395: }
                    396: 
                    397: /* 64 bit unsigned mul */
                    398: void OPPROTO op_mull_T0_T1(void)
                    399: {
                    400:     uint64_t res;
                    401:     res = (uint64_t)T0 * (uint64_t)T1;
                    402:     T1 = res >> 32;
                    403:     T0 = res;
                    404: }
                    405: 
                    406: /* 64 bit signed mul */
                    407: void OPPROTO op_imull_T0_T1(void)
                    408: {
                    409:     uint64_t res;
                    410:     res = (int64_t)((int32_t)T0) * (int64_t)((int32_t)T1);
                    411:     T1 = res >> 32;
                    412:     T0 = res;
                    413: }
                    414: 
                    415: /* 48 bit signed mul, top 32 bits */
                    416: void OPPROTO op_imulw_T0_T1(void)
                    417: {
                    418:   uint64_t res;
                    419:   res = (int64_t)((int32_t)T0) * (int64_t)((int32_t)T1);
                    420:   T0 = res >> 16;
                    421: }
                    422: 
                    423: void OPPROTO op_addq_T0_T1(void)
                    424: {
                    425:     uint64_t res;
                    426:     res = ((uint64_t)T1 << 32) | T0;
                    427:     res += ((uint64_t)(env->regs[PARAM2]) << 32) | (env->regs[PARAM1]);
                    428:     T1 = res >> 32;
                    429:     T0 = res;
                    430: }
                    431: 
                    432: void OPPROTO op_addq_lo_T0_T1(void)
                    433: {
                    434:     uint64_t res;
                    435:     res = ((uint64_t)T1 << 32) | T0;
                    436:     res += (uint64_t)(env->regs[PARAM1]);
                    437:     T1 = res >> 32;
                    438:     T0 = res;
                    439: }
                    440: 
                    441: void OPPROTO op_logicq_cc(void)
                    442: {
                    443:     env->NZF = (T1 & 0x80000000) | ((T0 | T1) != 0);
                    444: }
                    445: 
                    446: /* memory access */
                    447: 
1.1.1.2   root      448: #define MEMSUFFIX _raw
                    449: #include "op_mem.h"
1.1       root      450: 
1.1.1.2   root      451: #if !defined(CONFIG_USER_ONLY)
                    452: #define MEMSUFFIX _user
                    453: #include "op_mem.h"
                    454: #define MEMSUFFIX _kernel
                    455: #include "op_mem.h"
                    456: #endif
1.1       root      457: 
                    458: /* shifts */
                    459: 
                    460: /* T1 based */
                    461: 
                    462: void OPPROTO op_shll_T1_im(void)
                    463: {
                    464:     T1 = T1 << PARAM1;
                    465: }
                    466: 
                    467: void OPPROTO op_shrl_T1_im(void)
                    468: {
                    469:     T1 = (uint32_t)T1 >> PARAM1;
                    470: }
                    471: 
                    472: void OPPROTO op_shrl_T1_0(void)
                    473: {
                    474:     T1 = 0;
                    475: }
                    476: 
                    477: void OPPROTO op_sarl_T1_im(void)
                    478: {
                    479:     T1 = (int32_t)T1 >> PARAM1;
                    480: }
                    481: 
                    482: void OPPROTO op_sarl_T1_0(void)
                    483: {
                    484:     T1 = (int32_t)T1 >> 31;
                    485: }
                    486: 
                    487: void OPPROTO op_rorl_T1_im(void)
                    488: {
                    489:     int shift;
                    490:     shift = PARAM1;
                    491:     T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
                    492: }
                    493: 
                    494: void OPPROTO op_rrxl_T1(void)
                    495: {
                    496:     T1 = ((uint32_t)T1 >> 1) | ((uint32_t)env->CF << 31);
                    497: }
                    498: 
                    499: /* T1 based, set C flag */
                    500: void OPPROTO op_shll_T1_im_cc(void)
                    501: {
                    502:     env->CF = (T1 >> (32 - PARAM1)) & 1;
                    503:     T1 = T1 << PARAM1;
                    504: }
                    505: 
                    506: void OPPROTO op_shrl_T1_im_cc(void)
                    507: {
                    508:     env->CF = (T1 >> (PARAM1 - 1)) & 1;
                    509:     T1 = (uint32_t)T1 >> PARAM1;
                    510: }
                    511: 
                    512: void OPPROTO op_shrl_T1_0_cc(void)
                    513: {
                    514:     env->CF = (T1 >> 31) & 1;
                    515:     T1 = 0;
                    516: }
                    517: 
                    518: void OPPROTO op_sarl_T1_im_cc(void)
                    519: {
                    520:     env->CF = (T1 >> (PARAM1 - 1)) & 1;
                    521:     T1 = (int32_t)T1 >> PARAM1;
                    522: }
                    523: 
                    524: void OPPROTO op_sarl_T1_0_cc(void)
                    525: {
                    526:     env->CF = (T1 >> 31) & 1;
                    527:     T1 = (int32_t)T1 >> 31;
                    528: }
                    529: 
                    530: void OPPROTO op_rorl_T1_im_cc(void)
                    531: {
                    532:     int shift;
                    533:     shift = PARAM1;
                    534:     env->CF = (T1 >> (shift - 1)) & 1;
                    535:     T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
                    536: }
                    537: 
                    538: void OPPROTO op_rrxl_T1_cc(void)
                    539: {
                    540:     uint32_t c;
                    541:     c = T1 & 1;
                    542:     T1 = ((uint32_t)T1 >> 1) | ((uint32_t)env->CF << 31);
                    543:     env->CF = c;
                    544: }
                    545: 
                    546: /* T2 based */
                    547: void OPPROTO op_shll_T2_im(void)
                    548: {
                    549:     T2 = T2 << PARAM1;
                    550: }
                    551: 
                    552: void OPPROTO op_shrl_T2_im(void)
                    553: {
                    554:     T2 = (uint32_t)T2 >> PARAM1;
                    555: }
                    556: 
                    557: void OPPROTO op_shrl_T2_0(void)
                    558: {
                    559:     T2 = 0;
                    560: }
                    561: 
                    562: void OPPROTO op_sarl_T2_im(void)
                    563: {
                    564:     T2 = (int32_t)T2 >> PARAM1;
                    565: }
                    566: 
                    567: void OPPROTO op_sarl_T2_0(void)
                    568: {
                    569:     T2 = (int32_t)T2 >> 31;
                    570: }
                    571: 
                    572: void OPPROTO op_rorl_T2_im(void)
                    573: {
                    574:     int shift;
                    575:     shift = PARAM1;
                    576:     T2 = ((uint32_t)T2 >> shift) | (T2 << (32 - shift));
                    577: }
                    578: 
                    579: void OPPROTO op_rrxl_T2(void)
                    580: {
                    581:     T2 = ((uint32_t)T2 >> 1) | ((uint32_t)env->CF << 31);
                    582: }
                    583: 
                    584: /* T1 based, use T0 as shift count */
                    585: 
                    586: void OPPROTO op_shll_T1_T0(void)
                    587: {
                    588:     int shift;
                    589:     shift = T0 & 0xff;
                    590:     if (shift >= 32)
                    591:         T1 = 0;
                    592:     else
                    593:         T1 = T1 << shift;
                    594:     FORCE_RET();
                    595: }
                    596: 
                    597: void OPPROTO op_shrl_T1_T0(void)
                    598: {
                    599:     int shift;
                    600:     shift = T0 & 0xff;
                    601:     if (shift >= 32)
                    602:         T1 = 0;
                    603:     else
                    604:         T1 = (uint32_t)T1 >> shift;
                    605:     FORCE_RET();
                    606: }
                    607: 
                    608: void OPPROTO op_sarl_T1_T0(void)
                    609: {
                    610:     int shift;
                    611:     shift = T0 & 0xff;
                    612:     if (shift >= 32)
                    613:         shift = 31;
                    614:     T1 = (int32_t)T1 >> shift;
                    615: }
                    616: 
                    617: void OPPROTO op_rorl_T1_T0(void)
                    618: {
                    619:     int shift;
                    620:     shift = T0 & 0x1f;
                    621:     if (shift) {
                    622:         T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
                    623:     }
                    624:     FORCE_RET();
                    625: }
                    626: 
                    627: /* T1 based, use T0 as shift count and compute CF */
                    628: 
                    629: void OPPROTO op_shll_T1_T0_cc(void)
                    630: {
                    631:     int shift;
                    632:     shift = T0 & 0xff;
                    633:     if (shift >= 32) {
                    634:         if (shift == 32)
                    635:             env->CF = T1 & 1;
                    636:         else
                    637:             env->CF = 0;
                    638:         T1 = 0;
                    639:     } else if (shift != 0) {
                    640:         env->CF = (T1 >> (32 - shift)) & 1;
                    641:         T1 = T1 << shift;
                    642:     }
                    643:     FORCE_RET();
                    644: }
                    645: 
                    646: void OPPROTO op_shrl_T1_T0_cc(void)
                    647: {
                    648:     int shift;
                    649:     shift = T0 & 0xff;
                    650:     if (shift >= 32) {
                    651:         if (shift == 32)
                    652:             env->CF = (T1 >> 31) & 1;
                    653:         else
                    654:             env->CF = 0;
                    655:         T1 = 0;
                    656:     } else if (shift != 0) {
                    657:         env->CF = (T1 >> (shift - 1)) & 1;
                    658:         T1 = (uint32_t)T1 >> shift;
                    659:     }
                    660:     FORCE_RET();
                    661: }
                    662: 
                    663: void OPPROTO op_sarl_T1_T0_cc(void)
                    664: {
                    665:     int shift;
                    666:     shift = T0 & 0xff;
                    667:     if (shift >= 32) {
                    668:         env->CF = (T1 >> 31) & 1;
                    669:         T1 = (int32_t)T1 >> 31;
                    670:     } else {
                    671:         env->CF = (T1 >> (shift - 1)) & 1;
                    672:         T1 = (int32_t)T1 >> shift;
                    673:     }
                    674:     FORCE_RET();
                    675: }
                    676: 
                    677: void OPPROTO op_rorl_T1_T0_cc(void)
                    678: {
                    679:     int shift1, shift;
                    680:     shift1 = T0 & 0xff;
                    681:     shift = shift1 & 0x1f;
                    682:     if (shift == 0) {
                    683:         if (shift1 != 0)
                    684:             env->CF = (T1 >> 31) & 1;
                    685:     } else {
                    686:         env->CF = (T1 >> (shift - 1)) & 1;
                    687:         T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
                    688:     }
                    689:     FORCE_RET();
                    690: }
                    691: 
                    692: /* misc */
                    693: void OPPROTO op_clz_T0(void)
                    694: {
                    695:     int count;
                    696:     for (count = 32; T0 > 0; count--)
                    697:         T0 = T0 >> 1;
                    698:     T0 = count;
                    699:     FORCE_RET();
                    700: }
                    701: 
                    702: void OPPROTO op_sarl_T0_im(void)
                    703: {
                    704:     T0 = (int32_t)T0 >> PARAM1;
                    705: }
                    706: 
1.1.1.2   root      707: /* Sign/zero extend */
                    708: void OPPROTO op_sxth_T0(void)
1.1       root      709: {
                    710:   T0 = (int16_t)T0;
                    711: }
                    712: 
1.1.1.2   root      713: void OPPROTO op_sxth_T1(void)
1.1       root      714: {
                    715:   T1 = (int16_t)T1;
                    716: }
                    717: 
1.1.1.2   root      718: void OPPROTO op_sxtb_T1(void)
                    719: {
                    720:     T1 = (int8_t)T1;
                    721: }
                    722: 
                    723: void OPPROTO op_uxtb_T1(void)
                    724: {
                    725:     T1 = (uint8_t)T1;
                    726: }
                    727: 
                    728: void OPPROTO op_uxth_T1(void)
                    729: {
                    730:     T1 = (uint16_t)T1;
                    731: }
                    732: 
                    733: void OPPROTO op_sxtb16_T1(void)
                    734: {
                    735:     uint32_t res;
                    736:     res = (uint16_t)(int8_t)T1;
                    737:     res |= (uint32_t)(int8_t)(T1 >> 16) << 16;
                    738:     T1 = res;
                    739: }
                    740: 
                    741: void OPPROTO op_uxtb16_T1(void)
                    742: {
                    743:     uint32_t res;
                    744:     res = (uint16_t)(uint8_t)T1;
                    745:     res |= (uint32_t)(uint8_t)(T1 >> 16) << 16;
                    746:     T1 = res;
                    747: }
                    748: 
1.1       root      749: #define SIGNBIT (uint32_t)0x80000000
                    750: /* saturating arithmetic  */
                    751: void OPPROTO op_addl_T0_T1_setq(void)
                    752: {
                    753:   uint32_t res;
                    754: 
                    755:   res = T0 + T1;
                    756:   if (((res ^ T0) & SIGNBIT) && !((T0 ^ T1) & SIGNBIT))
                    757:       env->QF = 1;
                    758: 
                    759:   T0 = res;
                    760:   FORCE_RET();
                    761: }
                    762: 
                    763: void OPPROTO op_addl_T0_T1_saturate(void)
                    764: {
                    765:   uint32_t res;
                    766: 
                    767:   res = T0 + T1;
                    768:   if (((res ^ T0) & SIGNBIT) && !((T0 ^ T1) & SIGNBIT)) {
                    769:       env->QF = 1;
                    770:       if (T0 & SIGNBIT)
                    771:           T0 = 0x80000000;
                    772:       else
                    773:           T0 = 0x7fffffff;
                    774:   }
                    775:   else
                    776:     T0 = res;
                    777:   
                    778:   FORCE_RET();
                    779: }
                    780: 
                    781: void OPPROTO op_subl_T0_T1_saturate(void)
                    782: {
                    783:   uint32_t res;
                    784: 
                    785:   res = T0 - T1;
                    786:   if (((res ^ T0) & SIGNBIT) && ((T0 ^ T1) & SIGNBIT)) {
                    787:       env->QF = 1;
                    788:       if (T0 & SIGNBIT)
                    789:           T0 = 0x8000000;
                    790:       else
                    791:           T0 = 0x7fffffff;
                    792:   }
                    793:   else
                    794:     T0 = res;
                    795:   
                    796:   FORCE_RET();
                    797: }
                    798: 
                    799: void OPPROTO op_double_T1_saturate(void)
                    800: {
                    801:   int32_t val;
                    802: 
                    803:   val = T1;
                    804:   if (val >= 0x40000000) {
                    805:       T1 = 0x7fffffff;
                    806:       env->QF = 1;
                    807:   } else if (val <= (int32_t)0xc0000000) {
                    808:       T1 = 0x80000000;
                    809:       env->QF = 1;
                    810:   } else {
                    811:       T1 = val << 1;
                    812:   }
                    813:   FORCE_RET();
                    814: }
                    815: 
                    816: /* thumb shift by immediate */
                    817: void OPPROTO op_shll_T0_im_thumb(void)
                    818: {
                    819:     int shift;
                    820:     shift = PARAM1;
                    821:     if (shift != 0) {
                    822:        env->CF = (T1 >> (32 - shift)) & 1;
                    823:        T0 = T0 << shift;
                    824:     }
                    825:     env->NZF = T0;
                    826:     FORCE_RET();
                    827: }
                    828: 
                    829: void OPPROTO op_shrl_T0_im_thumb(void)
                    830: {
                    831:     int shift;
                    832: 
                    833:     shift = PARAM1;
                    834:     if (shift == 0) {
                    835:        env->CF = ((uint32_t)shift) >> 31;
                    836:        T0 = 0;
                    837:     } else {
                    838:        env->CF = (T0 >> (shift - 1)) & 1;
                    839:        T0 = T0 >> shift;
                    840:     }
                    841:     env->NZF = T0;
                    842:     FORCE_RET();
                    843: }
                    844: 
                    845: void OPPROTO op_sarl_T0_im_thumb(void)
                    846: {
                    847:     int shift;
                    848: 
                    849:     shift = PARAM1;
                    850:     if (shift == 0) {
                    851:        T0 = ((int32_t)T0) >> 31;
                    852:        env->CF = T0 & 1;
                    853:     } else {
                    854:        env->CF = (T0 >> (shift - 1)) & 1;
                    855:        T0 = ((int32_t)T0) >> shift;
                    856:     }
                    857:     env->NZF = T0;
                    858:     FORCE_RET();
                    859: }
                    860: 
                    861: /* exceptions */
                    862: 
                    863: void OPPROTO op_swi(void)
                    864: {
                    865:     env->exception_index = EXCP_SWI;
                    866:     cpu_loop_exit();
                    867: }
                    868: 
                    869: void OPPROTO op_undef_insn(void)
                    870: {
                    871:     env->exception_index = EXCP_UDEF;
                    872:     cpu_loop_exit();
                    873: }
                    874: 
                    875: void OPPROTO op_debug(void)
                    876: {
                    877:     env->exception_index = EXCP_DEBUG;
                    878:     cpu_loop_exit();
                    879: }
                    880: 
1.1.1.2   root      881: void OPPROTO op_wfi(void)
                    882: {
                    883:     env->exception_index = EXCP_HLT;
                    884:     env->halted = 1;
                    885:     cpu_loop_exit();
                    886: }
                    887: 
1.1.1.3 ! root      888: void OPPROTO op_bkpt(void)
        !           889: {
        !           890:     env->exception_index = EXCP_BKPT;
        !           891:     cpu_loop_exit();
        !           892: }
        !           893: 
1.1       root      894: /* VFP support.  We follow the convention used for VFP instrunctions:
                    895:    Single precition routines have a "s" suffix, double precision a
                    896:    "d" suffix.  */
                    897: 
                    898: #define VFP_OP(name, p) void OPPROTO op_vfp_##name##p(void)
                    899: 
                    900: #define VFP_BINOP(name) \
                    901: VFP_OP(name, s)             \
                    902: {                           \
                    903:     FT0s = float32_ ## name (FT0s, FT1s, &env->vfp.fp_status);    \
                    904: }                           \
                    905: VFP_OP(name, d)             \
                    906: {                           \
                    907:     FT0d = float64_ ## name (FT0d, FT1d, &env->vfp.fp_status);    \
                    908: }
                    909: VFP_BINOP(add)
                    910: VFP_BINOP(sub)
                    911: VFP_BINOP(mul)
                    912: VFP_BINOP(div)
                    913: #undef VFP_BINOP
                    914: 
                    915: #define VFP_HELPER(name)  \
                    916: VFP_OP(name, s)           \
                    917: {                         \
                    918:     do_vfp_##name##s();    \
                    919: }                         \
                    920: VFP_OP(name, d)           \
                    921: {                         \
                    922:     do_vfp_##name##d();    \
                    923: }
                    924: VFP_HELPER(abs)
                    925: VFP_HELPER(sqrt)
                    926: VFP_HELPER(cmp)
                    927: VFP_HELPER(cmpe)
                    928: #undef VFP_HELPER
                    929: 
                    930: /* XXX: Will this do the right thing for NANs.  Should invert the signbit
                    931:    without looking at the rest of the value.  */
                    932: VFP_OP(neg, s)
                    933: {
                    934:     FT0s = float32_chs(FT0s);
                    935: }
                    936: 
                    937: VFP_OP(neg, d)
                    938: {
                    939:     FT0d = float64_chs(FT0d);
                    940: }
                    941: 
                    942: VFP_OP(F1_ld0, s)
                    943: {
                    944:     union {
                    945:         uint32_t i;
                    946:         float32 s;
                    947:     } v;
                    948:     v.i = 0;
                    949:     FT1s = v.s;
                    950: }
                    951: 
                    952: VFP_OP(F1_ld0, d)
                    953: {
                    954:     union {
                    955:         uint64_t i;
                    956:         float64 d;
                    957:     } v;
                    958:     v.i = 0;
                    959:     FT1d = v.d;
                    960: }
                    961: 
                    962: /* Helper routines to perform bitwise copies between float and int.  */
                    963: static inline float32 vfp_itos(uint32_t i)
                    964: {
                    965:     union {
                    966:         uint32_t i;
                    967:         float32 s;
                    968:     } v;
                    969: 
                    970:     v.i = i;
                    971:     return v.s;
                    972: }
                    973: 
                    974: static inline uint32_t vfp_stoi(float32 s)
                    975: {
                    976:     union {
                    977:         uint32_t i;
                    978:         float32 s;
                    979:     } v;
                    980: 
                    981:     v.s = s;
                    982:     return v.i;
                    983: }
                    984: 
                    985: /* Integer to float conversion.  */
                    986: VFP_OP(uito, s)
                    987: {
                    988:     FT0s = uint32_to_float32(vfp_stoi(FT0s), &env->vfp.fp_status);
                    989: }
                    990: 
                    991: VFP_OP(uito, d)
                    992: {
                    993:     FT0d = uint32_to_float64(vfp_stoi(FT0s), &env->vfp.fp_status);
                    994: }
                    995: 
                    996: VFP_OP(sito, s)
                    997: {
                    998:     FT0s = int32_to_float32(vfp_stoi(FT0s), &env->vfp.fp_status);
                    999: }
                   1000: 
                   1001: VFP_OP(sito, d)
                   1002: {
                   1003:     FT0d = int32_to_float64(vfp_stoi(FT0s), &env->vfp.fp_status);
                   1004: }
                   1005: 
                   1006: /* Float to integer conversion.  */
                   1007: VFP_OP(toui, s)
                   1008: {
                   1009:     FT0s = vfp_itos(float32_to_uint32(FT0s, &env->vfp.fp_status));
                   1010: }
                   1011: 
                   1012: VFP_OP(toui, d)
                   1013: {
                   1014:     FT0s = vfp_itos(float64_to_uint32(FT0d, &env->vfp.fp_status));
                   1015: }
                   1016: 
                   1017: VFP_OP(tosi, s)
                   1018: {
                   1019:     FT0s = vfp_itos(float32_to_int32(FT0s, &env->vfp.fp_status));
                   1020: }
                   1021: 
                   1022: VFP_OP(tosi, d)
                   1023: {
                   1024:     FT0s = vfp_itos(float64_to_int32(FT0d, &env->vfp.fp_status));
                   1025: }
                   1026: 
                   1027: /* TODO: Set rounding mode properly.  */
                   1028: VFP_OP(touiz, s)
                   1029: {
                   1030:     FT0s = vfp_itos(float32_to_uint32_round_to_zero(FT0s, &env->vfp.fp_status));
                   1031: }
                   1032: 
                   1033: VFP_OP(touiz, d)
                   1034: {
                   1035:     FT0s = vfp_itos(float64_to_uint32_round_to_zero(FT0d, &env->vfp.fp_status));
                   1036: }
                   1037: 
                   1038: VFP_OP(tosiz, s)
                   1039: {
                   1040:     FT0s = vfp_itos(float32_to_int32_round_to_zero(FT0s, &env->vfp.fp_status));
                   1041: }
                   1042: 
                   1043: VFP_OP(tosiz, d)
                   1044: {
                   1045:     FT0s = vfp_itos(float64_to_int32_round_to_zero(FT0d, &env->vfp.fp_status));
                   1046: }
                   1047: 
                   1048: /* floating point conversion */
                   1049: VFP_OP(fcvtd, s)
                   1050: {
                   1051:     FT0d = float32_to_float64(FT0s, &env->vfp.fp_status);
                   1052: }
                   1053: 
                   1054: VFP_OP(fcvts, d)
                   1055: {
                   1056:     FT0s = float64_to_float32(FT0d, &env->vfp.fp_status);
                   1057: }
                   1058: 
                   1059: /* Get and Put values from registers.  */
                   1060: VFP_OP(getreg_F0, d)
                   1061: {
                   1062:   FT0d = *(float64 *)((char *) env + PARAM1);
                   1063: }
                   1064: 
                   1065: VFP_OP(getreg_F0, s)
                   1066: {
                   1067:   FT0s = *(float32 *)((char *) env + PARAM1);
                   1068: }
                   1069: 
                   1070: VFP_OP(getreg_F1, d)
                   1071: {
                   1072:   FT1d = *(float64 *)((char *) env + PARAM1);
                   1073: }
                   1074: 
                   1075: VFP_OP(getreg_F1, s)
                   1076: {
                   1077:   FT1s = *(float32 *)((char *) env + PARAM1);
                   1078: }
                   1079: 
                   1080: VFP_OP(setreg_F0, d)
                   1081: {
                   1082:   *(float64 *)((char *) env + PARAM1) = FT0d;
                   1083: }
                   1084: 
                   1085: VFP_OP(setreg_F0, s)
                   1086: {
                   1087:   *(float32 *)((char *) env + PARAM1) = FT0s;
                   1088: }
                   1089: 
                   1090: void OPPROTO op_vfp_movl_T0_fpscr(void)
                   1091: {
                   1092:     do_vfp_get_fpscr ();
                   1093: }
                   1094: 
                   1095: void OPPROTO op_vfp_movl_T0_fpscr_flags(void)
                   1096: {
1.1.1.3 ! root     1097:     T0 = env->vfp.xregs[ARM_VFP_FPSCR] & (0xf << 28);
1.1       root     1098: }
                   1099: 
                   1100: void OPPROTO op_vfp_movl_fpscr_T0(void)
                   1101: {
                   1102:     do_vfp_set_fpscr();
                   1103: }
                   1104: 
1.1.1.3 ! root     1105: void OPPROTO op_vfp_movl_T0_xreg(void)
        !          1106: {
        !          1107:     T0 = env->vfp.xregs[PARAM1];
        !          1108: }
        !          1109: 
        !          1110: void OPPROTO op_vfp_movl_xreg_T0(void)
        !          1111: {
        !          1112:     env->vfp.xregs[PARAM1] = T0;
        !          1113: }
        !          1114: 
1.1       root     1115: /* Move between FT0s to T0  */
                   1116: void OPPROTO op_vfp_mrs(void)
                   1117: {
                   1118:     T0 = vfp_stoi(FT0s);
                   1119: }
                   1120: 
                   1121: void OPPROTO op_vfp_msr(void)
                   1122: {
                   1123:     FT0s = vfp_itos(T0);
                   1124: }
                   1125: 
                   1126: /* Move between FT0d and {T0,T1} */
                   1127: void OPPROTO op_vfp_mrrd(void)
                   1128: {
                   1129:     CPU_DoubleU u;
                   1130:     
                   1131:     u.d = FT0d;
                   1132:     T0 = u.l.lower;
                   1133:     T1 = u.l.upper;
                   1134: }
                   1135: 
                   1136: void OPPROTO op_vfp_mdrr(void)
                   1137: {
                   1138:     CPU_DoubleU u;
                   1139:     
                   1140:     u.l.lower = T0;
                   1141:     u.l.upper = T1;
                   1142:     FT0d = u.d;
                   1143: }
                   1144: 
1.1.1.2   root     1145: /* Copy the most significant bit to T0 to all bits of T1.  */
                   1146: void OPPROTO op_signbit_T1_T0(void)
                   1147: {
                   1148:     T1 = (int32_t)T0 >> 31;
                   1149: }
                   1150: 
                   1151: void OPPROTO op_movl_cp15_T0(void)
1.1       root     1152: {
1.1.1.2   root     1153:     helper_set_cp15(env, PARAM1, T0);
                   1154:     FORCE_RET();
1.1       root     1155: }
                   1156: 
1.1.1.2   root     1157: void OPPROTO op_movl_T0_cp15(void)
1.1       root     1158: {
1.1.1.2   root     1159:     T0 = helper_get_cp15(env, PARAM1);
                   1160:     FORCE_RET();
1.1       root     1161: }
                   1162: 
1.1.1.2   root     1163: /* Access to user mode registers from privileged modes.  */
                   1164: void OPPROTO op_movl_T0_user(void)
1.1       root     1165: {
1.1.1.2   root     1166:     int regno = PARAM1;
                   1167:     if (regno == 13) {
                   1168:         T0 = env->banked_r13[0];
                   1169:     } else if (regno == 14) {
                   1170:         T0 = env->banked_r14[0];
                   1171:     } else if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
                   1172:         T0 = env->usr_regs[regno - 8];
                   1173:     } else {
                   1174:         T0 = env->regs[regno];
                   1175:     }
                   1176:     FORCE_RET();
1.1       root     1177: }
                   1178: 
1.1.1.2   root     1179: 
                   1180: void OPPROTO op_movl_user_T0(void)
1.1       root     1181: {
1.1.1.2   root     1182:     int regno = PARAM1;
                   1183:     if (regno == 13) {
                   1184:         env->banked_r13[0] = T0;
                   1185:     } else if (regno == 14) {
                   1186:         env->banked_r14[0] = T0;
                   1187:     } else if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
                   1188:         env->usr_regs[regno - 8] = T0;
                   1189:     } else {
                   1190:         env->regs[regno] = T0;
                   1191:     }
                   1192:     FORCE_RET();
1.1       root     1193: }
1.1.1.3 ! root     1194: 
        !          1195: void OPPROTO op_movl_T2_T0(void)
        !          1196: {
        !          1197:     T2 = T0;
        !          1198: }
        !          1199: 
        !          1200: void OPPROTO op_movl_T0_T2(void)
        !          1201: {
        !          1202:     T0 = T2;
        !          1203: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.