Skip to content

Commit e48354c

Browse files
committed
fix FPU decoding of single, double, real, and extended
1 parent 5a1fdb5 commit e48354c

2 files changed

Lines changed: 166 additions & 9 deletions

File tree

arch/M68K/M68KDisassembler.c

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2333,40 +2333,53 @@ static void d68020_fpu(m68k_info *info)
23332333

23342334
if (rm == 1) {
23352335
switch (src) {
2336-
case 0x00:
2336+
case 0x00: // long integer
23372337
ext->op_size.cpu_size = M68K_CPU_SIZE_LONG;
23382338
get_ea_mode_op(info, op0, info->ir, 4);
23392339
break;
23402340

2341-
case 0x06:
2341+
case 0x06: // byte integer
23422342
ext->op_size.cpu_size = M68K_CPU_SIZE_BYTE;
23432343
get_ea_mode_op(info, op0, info->ir, 1);
23442344
break;
23452345

2346-
case 0x04:
2346+
case 0x04: // word integer
23472347
ext->op_size.cpu_size = M68K_CPU_SIZE_WORD;
23482348
get_ea_mode_op(info, op0, info->ir, 2);
23492349
break;
23502350

2351-
case 0x01:
2351+
case 0x01: // single real
23522352
ext->op_size.type = M68K_SIZE_TYPE_FPU;
23532353
ext->op_size.fpu_size = M68K_FPU_SIZE_SINGLE;
23542354
get_ea_mode_op(info, op0, info->ir, 4);
2355-
op0->simm = BitsToFloat(op0->imm);
2356-
op0->type = M68K_OP_FP_SINGLE;
2355+
if (op0->type == M68K_OP_IMM) {
2356+
// reinterpret the immediate as float
2357+
op0->simm = BitsToFloat((uint32_t)op0->imm);
2358+
op0->type = M68K_OP_FP_SINGLE;
2359+
}
23572360
break;
23582361

2359-
case 0x05:
2362+
case 0x05: // double real
23602363
ext->op_size.type = M68K_SIZE_TYPE_FPU;
23612364
ext->op_size.fpu_size = M68K_FPU_SIZE_DOUBLE;
23622365
get_ea_mode_op(info, op0, info->ir, 8);
2363-
op0->type = M68K_OP_FP_DOUBLE;
2366+
if (op0->type == M68K_OP_IMM) {
2367+
// reinterpret the immediate as double
2368+
op0->dimm = BitsToDouble(op0->imm);
2369+
op0->type = M68K_OP_FP_DOUBLE;
2370+
}
23642371
break;
23652372

2366-
default:
2373+
case 0x02: // extended real
2374+
case 0x03: // packed decimal
23672375
ext->op_size.type = M68K_SIZE_TYPE_FPU;
23682376
ext->op_size.fpu_size = M68K_FPU_SIZE_EXTENDED;
2377+
get_ea_mode_op(info, op0, info->ir, 12);
23692378
break;
2379+
2380+
default:
2381+
d68000_invalid(info);
2382+
return;
23702383
}
23712384
} else {
23722385
op0->reg = M68K_REG_FP0 + src;

tests/details/m68k.yaml

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,3 +1242,147 @@ test_cases:
12421242
disp_offset: 4
12431243
br_disp: 0x30
12441244
br_disp_size: 2
1245+
1246+
-
1247+
input:
1248+
bytes: [ 0xf2, 0x10, 0x40, 0x00, 0xf2, 0x10, 0x44, 0x00, 0xf2, 0x10, 0x48, 0x00, 0xf2, 0x10, 0x4c, 0x00, 0xf2, 0x10, 0x50, 0x00, 0xf2, 0x10, 0x54, 0x00, 0xf2, 0x10, 0x58, 0x00 ]
1249+
arch: "m68k"
1250+
options: [ CS_OPT_DETAIL, CS_MODE_BIG_ENDIAN, CS_MODE_M68K_040 ]
1251+
address: 0x2000
1252+
expected:
1253+
insns:
1254+
-
1255+
asm_text: "fmove.l (a0), fp0"
1256+
details:
1257+
regs_read: [ a0 ]
1258+
regs_write: [ fp0 ]
1259+
m68k:
1260+
operands:
1261+
-
1262+
type: M68K_OP_MEM
1263+
address_mode: M68K_AM_REGI_ADDR
1264+
-
1265+
type: M68K_OP_REG
1266+
reg: fp0
1267+
-
1268+
asm_text: "fmove.s (a0), fp0"
1269+
details:
1270+
regs_read: [ a0 ]
1271+
regs_write: [ fp0 ]
1272+
m68k:
1273+
operands:
1274+
-
1275+
type: M68K_OP_MEM
1276+
address_mode: M68K_AM_REGI_ADDR
1277+
-
1278+
type: M68K_OP_REG
1279+
reg: fp0
1280+
-
1281+
asm_text: "fmove.x (a0), fp0"
1282+
details:
1283+
regs_read: [ a0 ]
1284+
regs_write: [ fp0 ]
1285+
m68k:
1286+
operands:
1287+
-
1288+
type: M68K_OP_MEM
1289+
address_mode: M68K_AM_REGI_ADDR
1290+
-
1291+
type: M68K_OP_REG
1292+
reg: fp0
1293+
-
1294+
asm_text: "fmove.x (a0), fp0"
1295+
details:
1296+
regs_read: [ a0 ]
1297+
regs_write: [ fp0 ]
1298+
m68k:
1299+
operands:
1300+
-
1301+
type: M68K_OP_MEM
1302+
address_mode: M68K_AM_REGI_ADDR
1303+
-
1304+
type: M68K_OP_REG
1305+
reg: fp0
1306+
-
1307+
asm_text: "fmove.w (a0), fp0"
1308+
details:
1309+
regs_read: [ a0 ]
1310+
regs_write: [ fp0 ]
1311+
m68k:
1312+
operands:
1313+
-
1314+
type: M68K_OP_MEM
1315+
address_mode: M68K_AM_REGI_ADDR
1316+
-
1317+
type: M68K_OP_REG
1318+
reg: fp0
1319+
-
1320+
asm_text: "fmove.d (a0), fp0"
1321+
details:
1322+
regs_read: [ a0 ]
1323+
regs_write: [ fp0 ]
1324+
m68k:
1325+
operands:
1326+
-
1327+
type: M68K_OP_MEM
1328+
address_mode: M68K_AM_REGI_ADDR
1329+
-
1330+
type: M68K_OP_REG
1331+
reg: fp0
1332+
-
1333+
asm_text: "fmove.b (a0), fp0"
1334+
details:
1335+
regs_read: [ a0 ]
1336+
regs_write: [ fp0 ]
1337+
m68k:
1338+
operands:
1339+
-
1340+
type: M68K_OP_MEM
1341+
address_mode: M68K_AM_REGI_ADDR
1342+
-
1343+
type: M68K_OP_REG
1344+
reg: fp0
1345+
-
1346+
input:
1347+
bytes: [ 0xf2, 0x3c, 0x44, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0xf2, 0x3c, 0x54, 0x00, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x3c, 0x54, 0xa2, 0xbf, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
1348+
arch: "m68k"
1349+
options: [ CS_OPT_DETAIL, CS_MODE_BIG_ENDIAN, CS_MODE_M68K_040 ]
1350+
address: 0x2000
1351+
expected:
1352+
insns:
1353+
-
1354+
asm_text: "fmove.s #1.500000, fp0"
1355+
details:
1356+
regs_write: [ fp0 ]
1357+
m68k:
1358+
operands:
1359+
-
1360+
type: M68K_OP_FP_SINGLE
1361+
simm: 1.500000
1362+
-
1363+
type: M68K_OP_REG
1364+
reg: fp0
1365+
-
1366+
asm_text: "fmove.d #2.500000, fp0"
1367+
details:
1368+
regs_write: [ fp0 ]
1369+
m68k:
1370+
operands:
1371+
-
1372+
type: M68K_OP_FP_DOUBLE
1373+
dimm: 2.500000
1374+
-
1375+
type: M68K_OP_REG
1376+
reg: fp0
1377+
-
1378+
asm_text: "fadd.d #-0.500000, fp1"
1379+
details:
1380+
regs_write: [ fp1 ]
1381+
m68k:
1382+
operands:
1383+
-
1384+
type: M68K_OP_FP_DOUBLE
1385+
dimm: -0.500000
1386+
-
1387+
type: M68K_OP_REG
1388+
reg: fp1

0 commit comments

Comments
 (0)