Search
lxdream.org :: lxdream/src/aica/armdasm.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/aica/armdasm.c
changeset 13:28aea89fb9c6
prev11:0a82ef380c45
next14:fc481a638848
author nkeynes
date Mon Dec 12 10:09:24 2005 +0000 (14 years ago)
permissions -rw-r--r--
last change Fix a few minor arm dasm issues
file annotate diff log raw
1.1 --- a/src/aica/armdasm.c Sun Dec 11 12:00:09 2005 +0000
1.2 +++ b/src/aica/armdasm.c Mon Dec 12 10:09:24 2005 +0000
1.3 @@ -32,10 +32,12 @@
1.4 #define DISP24(ir) ((ir&0x00FFFFFF))
1.5 #define FSXC(ir) msrFieldMask[RN(ir)]
1.6 #define ROTIMM12(ir) ROTATE_RIGHT_LONG(IMM8(ir),IMMROT(ir))
1.7 +#define SIGNEXT24(n) ((n&0x00800000) ? (n|0xFF000000) : (n&0x00FFFFFF))
1.8 +
1.9
1.10
1.11 const struct reg_desc_struct arm_reg_map[] =
1.12 - { {"R0", REG_INT, &armr.r[0]}, {"R1", REG_INT, &armr.r[1]},
1.13 + { {"R0", REG_INT, &armr.r[0]}, {"R1", REG_INT, &armr.r[1]},
1.14 {"R2", REG_INT, &armr.r[2]}, {"R3", REG_INT, &armr.r[3]},
1.15 {"R4", REG_INT, &armr.r[4]}, {"R5", REG_INT, &armr.r[5]},
1.16 {"R6", REG_INT, &armr.r[6]}, {"R7", REG_INT, &armr.r[7]},
1.17 @@ -73,7 +75,12 @@
1.18 if( IFLAG(ir) == 0 ) {
1.19 switch(SHIFT(ir)) {
1.20 case 0: /* (Rm << imm) */
1.21 - return snprintf(buf, len, "R%d << %d", RM(ir), SHIFTIMM(ir) );
1.22 + tmp = SHIFTIMM(ir);
1.23 + if( tmp != 0 ) {
1.24 + return snprintf(buf, len, "R%d << %d", RM(ir), tmp );
1.25 + } else {
1.26 + return snprintf(buf, len, "R%d", RM(ir));
1.27 + }
1.28 case 1: /* (Rm << Rs) */
1.29 return snprintf(buf, len, "R%d << R%d", RM(ir), RS(ir) );
1.30 case 2: /* (Rm >> imm) */
1.31 @@ -107,7 +114,12 @@
1.32
1.33 switch(SHIFT(ir)) {
1.34 case 0: /* (Rm << imm) */
1.35 - return snprintf( buf, len, "R%d << %d", RM(ir), SHIFTIMM(ir) );
1.36 + tmp = SHIFTIMM(ir);
1.37 + if( tmp != 0 ) {
1.38 + return snprintf( buf, len, "R%d << %d", RM(ir), tmp );
1.39 + } else {
1.40 + return snprintf( buf, len, "R%d", RM(ir) );
1.41 + }
1.42 case 2: /* (Rm >> imm) */
1.43 return snprintf( buf, len, "R%d >> %d", RM(ir), SHIFTIMM(ir) );
1.44 case 4: /* (Rm >>> imm) */
1.45 @@ -123,18 +135,23 @@
1.46 }
1.47 }
1.48
1.49 -static int arm_disasm_address_operand( uint32_t ir, char *buf, int len )
1.50 +static int arm_disasm_address_operand( uint32_t ir, char *buf, int len, int pc )
1.51 {
1.52 char shift[32];
1.53
1.54 - char sign = UFLAG(ir) ? '-' : '+';
1.55 + char sign = UFLAG(ir) ? '+' : '-';
1.56 /* I P U . W */
1.57 switch( (ir>>21)&0x19 ) {
1.58 case 0: /* Rn -= imm offset (post-indexed) [5.2.8 A5-28] */
1.59 case 1:
1.60 return snprintf( buf, len, "[R%d], R%d %c= %04X", RN(ir), RN(ir), sign, IMM12(ir) );
1.61 case 8: /* Rn - imm offset [5.2.2 A5-20] */
1.62 + if( RN(ir) == 15 ) { /* PC relative - decode here */
1.63 + return snprintf( buf, len, "[$%08Xh]", pc + 8 +
1.64 + (UFLAG(ir) ? IMM12(ir) : -IMM12(ir)) );
1.65 + } else {
1.66 return snprintf( buf, len, "[R%d %c %04X]", RN(ir), sign, IMM12(ir) );
1.67 + }
1.68 case 9: /* Rn -= imm offset (pre-indexed) [5.2.5 A5-24] */
1.69 return snprintf( buf, len, "[R%d %c= %04X]", RN(ir), sign, IMM12(ir) );
1.70 case 16: /* Rn -= Rm (post-indexed) [5.2.10 A5-32 ] */
1.71 @@ -387,7 +404,7 @@
1.72 }
1.73 break;
1.74 case 1: /* Load/store */
1.75 - arm_disasm_address_operand( ir, operand, sizeof(operand) );
1.76 + arm_disasm_address_operand( ir, operand, sizeof(operand), pc );
1.77 switch( (ir>>20)&0x17 ) {
1.78 case 0:
1.79 case 16:
1.80 @@ -423,9 +440,18 @@
1.81 break;
1.82 }
1.83 break;
1.84 - case 2: /* Load/store multiple, branch*/
1.85 + case 2:
1.86 + if( (ir & 0x02000000) == 0x02000000 ) {
1.87 + int32_t offset = SIGNEXT24(ir&0x00FFFFFF) << 2;
1.88 + if( (ir & 0x01000000) == 0x01000000 ) {
1.89 + snprintf( buf, len, "BL%s $%08Xh", cond, pc + offset + 8 );
1.90 + } else {
1.91 + snprintf( buf, len, "B%s $%08Xh", cond, pc + offset + 8 );
1.92 + }
1.93 + } else {
1.94 + /* Load/store multiple */
1.95 j = snprintf( buf, len, LFLAG(ir) ? "LDM%s%s R%d%c,":"STM%s%s R%d%c,",
1.96 - ldmModes[(ir>>23)&0x03], cond, RN(ir), WFLAG(ir)?'!':' ' );
1.97 + ldmModes[(ir>>23)&0x03], cond, RN(ir), WFLAG(ir)?'!':' ' );
1.98 buf += j;
1.99 len -= j;
1.100 for( i = 0; i<16 && len > 2; i++ ) {
1.101 @@ -439,10 +465,11 @@
1.102 buf[0] = '^';
1.103 buf[1] = '\0';
1.104 }
1.105 - break;
1.106 + }
1.107 + break;
1.108 case 3: /* Copro */
1.109 - UNIMP(ir);
1.110 - break;
1.111 + UNIMP(ir);
1.112 + break;
1.113 }
1.114
1.115
.