Search
lxdream.org :: lxdream/src/aica/armdasm.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/aica/armdasm.c
changeset 7:976a16e92aab
prev4:7d6f596ce577
next11:0a82ef380c45
author nkeynes
date Sun Dec 12 07:44:09 2004 +0000 (14 years ago)
permissions -rw-r--r--
last change More progress on arm
file annotate diff log raw
1.1 --- a/src/aica/armdasm.c Sat Oct 02 05:49:12 2004 +0000
1.2 +++ b/src/aica/armdasm.c Sun Dec 12 07:44:09 2004 +0000
1.3 @@ -5,7 +5,8 @@
1.4 * under the terms of the GNU General Public License version 2 or later.
1.5 */
1.6
1.7 -#include "armcore.h"
1.8 +#include "aica/armcore.h"
1.9 +#include <stdlib.h>
1.10
1.11 #define COND(ir) (ir>>28)
1.12 #define OPCODE(ir) ((ir>>20)&0x1F)
1.13 @@ -15,7 +16,7 @@
1.14 #define PFLAG(ir) (ir&0x01000000)
1.15 #define UFLAG(ir) (ir&0x00800000)
1.16 #define BFLAG(ir) (ir&0x00400000)
1.17 -#define WFLAG(ir) (IR&0x00200000)
1.18 +#define WFLAG(ir) (ir&0x00200000)
1.19 #define LFLAG(ir) SFLAG(ir)
1.20 #define RN(ir) ((ir>>16)&0x0F)
1.21 #define RD(ir) ((ir>>12)&0x0F)
1.22 @@ -24,8 +25,8 @@
1.23
1.24 #define IMM8(ir) (ir&0xFF)
1.25 #define IMM12(ir) (ir&0xFFF)
1.26 -#define SHIFTIMM(ir) ((ir>>7)0x1F)
1.27 -#define IMMROT(ir) ((ir>>7)&1E)
1.28 +#define SHIFTIMM(ir) ((ir>>7)&0x1F)
1.29 +#define IMMROT(ir) ((ir>>7)&0x1E)
1.30 #define SHIFT(ir) ((ir>>4)&0x07)
1.31 #define DISP24(ir) ((ir&0x00FFFFFF))
1.32 #define FSXC(ir) msrFieldMask[RN(ir)]
1.33 @@ -37,13 +38,101 @@
1.34 /* fsxc */
1.35 char *msrFieldMask[] = { "", "c", "x", "xc", "s", "sc", "sx", "sxc",
1.36 "f", "fc", "fx", "fxc", "fs", "fsc", "fsx", "fsxc" };
1.37 +char *ldmModes[] = { "DA", "IA", "DB", "IB" };
1.38
1.39 #define UNIMP(ir) snprintf( buf, len, "??? " )
1.40
1.41 -int arm_disasm_instruction( int pc, char *buf, int len )
1.42 +int arm_disasm_shift_operand( uint32_t ir, char *buf, int len )
1.43 {
1.44 + uint32_t operand, tmp;
1.45 + if( IFLAG(ir) == 0 ) {
1.46 + switch(SHIFT(ir)) {
1.47 + case 0: /* (Rm << imm) */
1.48 + return snprintf(buf, len, "R%d << %d", RM(ir), SHIFTIMM(ir) );
1.49 + case 1: /* (Rm << Rs) */
1.50 + return snprintf(buf, len, "R%d << R%d", RM(ir), RS(ir) );
1.51 + case 2: /* (Rm >> imm) */
1.52 + return snprintf(buf, len, "R%d >> %d", RM(ir), SHIFTIMM(ir) );
1.53 + case 3: /* (Rm >> Rs) */
1.54 + return snprintf(buf, len, "R%d >> R%d", RM(ir), RS(ir) );
1.55 + case 4: /* (Rm >>> imm) */
1.56 + return snprintf(buf, len, "R%d >>> %d", RM(ir), SHIFTIMM(ir) );
1.57 + case 5: /* (Rm >>> Rs) */
1.58 + return snprintf(buf, len, "R%d >>> R%d", RM(ir), RS(ir) );
1.59 + case 6:
1.60 + tmp = SHIFTIMM(ir);
1.61 + if( tmp == 0 ) /* RRX aka rotate with carry */
1.62 + return snprintf(buf, len, "R%d roc 1", RM(ir) );
1.63 + else
1.64 + return snprintf(buf, len, "R%d rot %d", RM(ir), SHIFTIMM(ir) );
1.65 + case 7:
1.66 + return snprintf(buf, len, "R%d rot R%d", RM(ir), RS(ir) );
1.67 + }
1.68 + } else {
1.69 + operand = IMM8(ir);
1.70 + tmp = IMMROT(ir);
1.71 + operand = ROTATE_RIGHT_LONG(operand, tmp);
1.72 + return snprintf(buf, len, "%08X", operand );
1.73 + }
1.74 +}
1.75 +
1.76 +static int arm_disasm_address_index( uint32_t ir, char *buf, int len )
1.77 +{
1.78 + uint32_t tmp;
1.79 +
1.80 + switch(SHIFT(ir)) {
1.81 + case 0: /* (Rm << imm) */
1.82 + return snprintf( buf, len, "R%d << %d", RM(ir), SHIFTIMM(ir) );
1.83 + case 2: /* (Rm >> imm) */
1.84 + return snprintf( buf, len, "R%d >> %d", RM(ir), SHIFTIMM(ir) );
1.85 + case 4: /* (Rm >>> imm) */
1.86 + return snprintf( buf, len, "R%d >>> %d", RM(ir), SHIFTIMM(ir) );
1.87 + case 6:
1.88 + tmp = SHIFTIMM(ir);
1.89 + if( tmp == 0 ) /* RRX aka rotate with carry */
1.90 + return snprintf( buf, len, "R%d roc 1", RM(ir) );
1.91 + else
1.92 + return snprintf( buf, len, "R%d rot %d", RM(ir), tmp );
1.93 + default:
1.94 + return UNIMP(ir);
1.95 + }
1.96 +}
1.97 +
1.98 +static int arm_disasm_address_operand( uint32_t ir, char *buf, int len )
1.99 +{
1.100 + char shift[32];
1.101 +
1.102 + char sign = UFLAG(ir) ? '-' : '+';
1.103 + /* I P U . W */
1.104 + switch( (ir>>21)&0x19 ) {
1.105 + case 0: /* Rn -= imm offset (post-indexed) [5.2.8 A5-28] */
1.106 + case 1:
1.107 + return snprintf( buf, len, "[R%d], R%d %c= %04X", RN(ir), RN(ir), sign, IMM12(ir) );
1.108 + case 8: /* Rn - imm offset [5.2.2 A5-20] */
1.109 + return snprintf( buf, len, "[R%d %c %04X]", RN(ir), sign, IMM12(ir) );
1.110 + case 9: /* Rn -= imm offset (pre-indexed) [5.2.5 A5-24] */
1.111 + return snprintf( buf, len, "[R%d %c= %04X]", RN(ir), sign, IMM12(ir) );
1.112 + case 16: /* Rn -= Rm (post-indexed) [5.2.10 A5-32 ] */
1.113 + case 17:
1.114 + arm_disasm_address_index( ir, shift, sizeof(shift) );
1.115 + return snprintf( buf, len, "[R%d], R%d %c= %s", RN(ir), RN(ir), sign, shift );
1.116 + case 24: /* Rn - Rm [5.2.4 A5-23] */
1.117 + arm_disasm_address_index( ir, shift, sizeof(shift) );
1.118 + return snprintf( buf, len, "[R%d %c %s]", RN(ir), sign, shift );
1.119 + case 25: /* RN -= Rm (pre-indexed) [5.2.7 A5-26] */
1.120 + arm_disasm_address_index( ir, shift, sizeof(shift) );
1.121 + return snprintf( buf, len, "[R%d %c= %s]", RN(ir), sign, shift );
1.122 + default:
1.123 + return UNIMP(ir); /* Unreachable */
1.124 + }
1.125 +}
1.126 +
1.127 +int arm_disasm_instruction( uint32_t pc, char *buf, int len )
1.128 +{
1.129 + char operand[32];
1.130 uint32_t ir = arm_mem_read_long(pc);
1.131 -
1.132 + int i,j;
1.133 +
1.134 if( COND(ir) == 0x0F ) {
1.135 UNIMP(ir);
1.136 return pc+4;
1.137 @@ -153,176 +242,116 @@
1.138
1.139 switch(OPCODE(ir)) {
1.140 case 0: /* AND Rd, Rn, operand */
1.141 - RD(ir) = RN(ir) & arm_get_shift_operand(ir);
1.142 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.143 + snprintf(buf, len, "AND%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.144 break;
1.145 case 1: /* ANDS Rd, Rn, operand */
1.146 - operand = arm_get_shift_operand_s(ir) & RN(ir);
1.147 - RD(ir) = operand;
1.148 - if( RDn(ir) == 15 ) {
1.149 - arm_restore_cpsr();
1.150 - } else {
1.151 - armr.n = operand>>31;
1.152 - armr.z = (operand == 0);
1.153 - armr.c = armr.shift_c;
1.154 - }
1.155 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.156 + snprintf(buf, len, "ANDS%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.157 break;
1.158 case 2: /* EOR Rd, Rn, operand */
1.159 - RD(ir) = RN(ir) ^ arm_get_shift_operand(ir);
1.160 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.161 + snprintf(buf, len, "EOR%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.162 break;
1.163 case 3: /* EORS Rd, Rn, operand */
1.164 - operand = arm_get_shift_operand_s(ir) ^ RN(ir);
1.165 - RD(ir) = operand;
1.166 - if( RDn(ir) == 15 ) {
1.167 - arm_restore_cpsr();
1.168 - } else {
1.169 - armr.n = operand>>31;
1.170 - armr.z = (operand == 0);
1.171 - armr.c = armr.shift_c;
1.172 - }
1.173 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.174 + snprintf(buf, len, "EORS%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.175 break;
1.176 case 4: /* SUB Rd, Rn, operand */
1.177 - RD(ir) = RN(ir) - arm_get_shift_operand(ir);
1.178 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.179 + snprintf(buf, len, "SUB%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.180 break;
1.181 case 5: /* SUBS Rd, Rn, operand */
1.182 - operand = RN(ir);
1.183 - operand2 = arm_get_shift_operand(ir)
1.184 - tmp = operand - operand2;
1.185 - RD(ir) = tmp;
1.186 - if( RDn(ir) == 15 ) {
1.187 - arm_restore_cpsr();
1.188 - } else {
1.189 - armr.n = tmp>>31;
1.190 - armr.z = (tmp == 0);
1.191 - armr.c = IS_NOTBORROW(tmp,operand,operand2);
1.192 - armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
1.193 - }
1.194 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.195 + snprintf(buf, len, "SUBS%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.196 break;
1.197 - case 6: /* RSB Rd, operand, Rn */
1.198 - RD(ir) = arm_get_shift_operand(ir) - RN(ir);
1.199 + case 6: /* RSB Rd, Rn, operand */
1.200 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.201 + snprintf(buf, len, "RSB%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.202 break;
1.203 - case 7: /* RSBS Rd, operand, Rn */
1.204 - operand = arm_get_shift_operand(ir);
1.205 - operand2 = RN(ir);
1.206 - tmp = operand - operand2;
1.207 - RD(ir) = tmp;
1.208 - if( RDn(ir) == 15 ) {
1.209 - arm_restore_cpsr();
1.210 - } else {
1.211 - armr.n = tmp>>31;
1.212 - armr.z = (tmp == 0);
1.213 - armr.c = IS_NOTBORROW(tmp,operand,operand2);
1.214 - armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
1.215 - }
1.216 + case 7: /* RSBS Rd, Rn, operand */
1.217 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.218 + snprintf(buf, len, "RSBS%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.219 break;
1.220 case 8: /* ADD Rd, Rn, operand */
1.221 - RD(ir) = RN(ir) + arm_get_shift_operand(ir);
1.222 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.223 + snprintf(buf, len, "ADD%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.224 break;
1.225 case 9: /* ADDS Rd, Rn, operand */
1.226 - operand = arm_get_shift_operand(ir);
1.227 - operand2 = RN(ir);
1.228 - tmp = operand + operand2
1.229 - RD(ir) = tmp;
1.230 - if( RDn(ir) == 15 ) {
1.231 - arm_restore_cpsr();
1.232 - } else {
1.233 - armr.n = tmp>>31;
1.234 - armr.z = (tmp == 0);
1.235 - armr.c = IS_CARRY(tmp,operand,operand2);
1.236 - armr.v = IS_ADDOVERFLOW(tmp,operand,operand2);
1.237 - }
1.238 - break;
1.239 - case 10: /* ADC */
1.240 - case 11: /* ADCS */
1.241 - case 12: /* SBC */
1.242 - case 13: /* SBCS */
1.243 - case 14: /* RSC */
1.244 - case 15: /* RSCS */
1.245 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.246 + snprintf(buf, len, "ADDS%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.247 break;
1.248 - case 17: /* TST Rn, operand */
1.249 - operand = arm_get_shift_operand_s(ir) & RN(ir);
1.250 - armr.n = operand>>31;
1.251 - armr.z = (operand == 0);
1.252 - armr.c = armr.shift_c;
1.253 + case 10: /* ADC Rd, Rn, operand */
1.254 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.255 + snprintf(buf, len, "ADC%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.256 break;
1.257 - case 19: /* TEQ Rn, operand */
1.258 - operand = arm_get_shift_operand_s(ir) ^ RN(ir);
1.259 - armr.n = operand>>31;
1.260 - armr.z = (operand == 0);
1.261 - armr.c = armr.shift_c;
1.262 - break;
1.263 - case 21: /* CMP Rn, operand */
1.264 - operand = RN(ir);
1.265 - operand2 = arm_get_shift_operand(ir)
1.266 - tmp = operand - operand2;
1.267 - armr.n = tmp>>31;
1.268 - armr.z = (tmp == 0);
1.269 - armr.c = IS_NOTBORROW(tmp,operand,operand2);
1.270 - armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
1.271 + case 11: /* ADCS Rd, Rn, operand */
1.272 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.273 + snprintf(buf, len, "ADCS%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.274 break;
1.275 - case 23: /* CMN Rn, operand */
1.276 - operand = RN(ir);
1.277 - operand2 = arm_get_shift_operand(ir)
1.278 - tmp = operand + operand2;
1.279 - armr.n = tmp>>31;
1.280 - armr.z = (tmp == 0);
1.281 - armr.c = IS_CARRY(tmp,operand,operand2);
1.282 - armr.v = IS_ADDOVERFLOW(tmp,operand,operand2);
1.283 + case 12: /* SBC Rd, Rn, operand */
1.284 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.285 + snprintf(buf, len, "SBC%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.286 + break;
1.287 + case 13: /* SBCS Rd, Rn, operand */
1.288 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.289 + snprintf(buf, len, "SBCS%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.290 + break;
1.291 + case 14: /* RSC Rd, Rn, operand */
1.292 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.293 + snprintf(buf, len, "RSC%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.294 + break;
1.295 + case 15: /* RSCS Rd, Rn, operand */
1.296 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.297 + snprintf(buf, len, "RSCS%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.298 + break;
1.299 + case 16: /* TST Rd, Rn, operand */
1.300 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.301 + snprintf(buf, len, "TST%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.302 + break;
1.303 + case 18: /* TEQ Rd, Rn, operand */
1.304 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.305 + snprintf(buf, len, "TEQ%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.306 + break;
1.307 + case 20: /* CMP Rd, Rn, operand */
1.308 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.309 + snprintf(buf, len, "CMP%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.310 + break;
1.311 + case 22: /* CMN Rd, Rn, operand */
1.312 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.313 + snprintf(buf, len, "CMN%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.314 break;
1.315 case 24: /* ORR Rd, Rn, operand */
1.316 - RD(ir) = RN(ir) | arm_get_shift_operand(ir);
1.317 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.318 + snprintf(buf, len, "ORR%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.319 break;
1.320 case 25: /* ORRS Rd, Rn, operand */
1.321 - operand = arm_get_shift_operand_s(ir) | RN(ir);
1.322 - RD(ir) = operand;
1.323 - if( RDn(ir) == 15 ) {
1.324 - arm_restore_cpsr();
1.325 - } else {
1.326 - armr.n = operand>>31;
1.327 - armr.z = (operand == 0);
1.328 - armr.c = armr.shift_c;
1.329 - }
1.330 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.331 + snprintf(buf, len, "ORRS%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.332 break;
1.333 - case 26: /* MOV Rd, operand */
1.334 - RD(ir) = arm_get_shift_operand(ir);
1.335 + case 26: /* MOV Rd, Rn, operand */
1.336 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.337 + snprintf(buf, len, "MOV%s R%d, %s", cond, RD(ir), operand);
1.338 break;
1.339 - case 27: /* MOVS Rd, operand */
1.340 - operand = arm_get_shift_operand_s(ir);
1.341 - RD(ir) = operand;
1.342 - if( RDn(ir) == 15 ) {
1.343 - arm_restore_cpsr();
1.344 - } else {
1.345 - armr.n = operand>>31;
1.346 - armr.z = (operand == 0);
1.347 - armr.c = armr.shift_c;
1.348 - }
1.349 + case 27: /* MOVS Rd, Rn, operand */
1.350 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.351 + snprintf(buf, len, "MOVS%s R%d, %s", cond, RD(ir), operand);
1.352 break;
1.353 case 28: /* BIC Rd, Rn, operand */
1.354 - RD(ir) = RN(ir) & (~arm_get_shift_operand(ir));
1.355 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.356 + snprintf(buf, len, "BIC%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.357 break;
1.358 case 29: /* BICS Rd, Rn, operand */
1.359 - operand = RN(ir) & (~arm_get_shift_operand_s(ir));
1.360 - RD(ir) = operand;
1.361 - if( RDn(ir) == 15 ) {
1.362 - arm_restore_cpsr();
1.363 - } else {
1.364 - armr.n = operand>>31;
1.365 - armr.z = (operand == 0);
1.366 - armr.c = armr.shift_c;
1.367 - }
1.368 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.369 + snprintf(buf, len, "BICS%s R%d, R%d, %s", cond, RD(ir), RN(ir), operand);
1.370 break;
1.371 - case 30: /* MVN Rd, operand */
1.372 - RD(ir) = ~arm_get_shift_operand(ir);
1.373 + case 30: /* MVN Rd, Rn, operand */
1.374 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.375 + snprintf(buf, len, "MVN%s R%d, %s", cond, RD(ir), operand);
1.376 break;
1.377 - case 31: /* MVNS Rd, operand */
1.378 - operand = ~arm_get_shift_operand_s(ir);
1.379 - RD(ir) = operand;
1.380 - if( RDn(ir) == 15 ) {
1.381 - arm_restore_cpsr();
1.382 - } else {
1.383 - armr.n = operand>>31;
1.384 - armr.z = (operand == 0);
1.385 - armr.c = armr.shift_c;
1.386 - }
1.387 + case 31: /* MVNS Rd, Rn, operand */
1.388 + arm_disasm_shift_operand(ir, operand, sizeof(operand));
1.389 + snprintf(buf, len, "MVNS%s R%d, %s", cond, RD(ir), operand);
1.390 break;
1.391 default:
1.392 UNIMP(ir);
1.393 @@ -330,10 +359,61 @@
1.394 }
1.395 break;
1.396 case 1: /* Load/store */
1.397 + arm_disasm_address_operand( ir, operand, sizeof(operand) );
1.398 + switch( (ir>>20)&0x17 ) {
1.399 + case 0:
1.400 + case 16:
1.401 + case 18:
1.402 + snprintf(buf, len, "STR%s R%d, %s", cond, RD(ir), operand );
1.403 + break;
1.404 + case 1:
1.405 + case 17:
1.406 + case 19:
1.407 + snprintf(buf, len, "LDR%s R%d, %s", cond, RD(ir), operand );
1.408 + break;
1.409 + case 2:
1.410 + snprintf(buf, len, "STRT%s R%d, %s", cond, RD(ir), operand );
1.411 + break;
1.412 + case 3:
1.413 + snprintf(buf, len, "LDRT%s R%d, %s", cond, RD(ir), operand );
1.414 + break;
1.415 + case 4:
1.416 + case 20:
1.417 + case 22:
1.418 + snprintf(buf, len, "STRB%s R%d, %s", cond, RD(ir), operand );
1.419 + break;
1.420 + case 5:
1.421 + case 21:
1.422 + case 23:
1.423 + snprintf(buf, len, "LDRB%s R%d, %s", cond, RD(ir), operand );
1.424 + break;
1.425 + case 6:
1.426 + snprintf(buf, len, "STRBT%s R%d, %s", cond, RD(ir), operand );
1.427 + break;
1.428 + case 7:
1.429 + snprintf(buf, len, "LDRBT%s R%d, %s", cond, RD(ir), operand );
1.430 + break;
1.431 + }
1.432 break;
1.433 case 2: /* Load/store multiple, branch*/
1.434 + j = snprintf( buf, len, LFLAG(ir) ? "LDM%s%s R%d%c,":"STM%s%s R%d%c,",
1.435 + ldmModes[(ir>>23)&0x03], cond, RN(ir), WFLAG(ir)?'!':' ' );
1.436 + buf += j;
1.437 + len -= j;
1.438 + for( i = 0; i<16 && len > 2; i++ ) {
1.439 + if( (ir >> i)&1 ) {
1.440 + j = snprintf( buf, len, "R%d", i );
1.441 + buf+=j;
1.442 + len-=j;
1.443 + }
1.444 + }
1.445 + if( SFLAG(ir) && len > 0 ) {
1.446 + buf[0] = '^';
1.447 + buf[1] = '\0';
1.448 + }
1.449 break;
1.450 case 3: /* Copro */
1.451 + UNIMP(ir);
1.452 break;
1.453 }
1.454
.