mirror of
https://github.com/zydeco/minivmac4ios.git
synced 2024-11-26 00:49:20 +00:00
3073 lines
69 KiB
C
Executable File
3073 lines
69 KiB
C
Executable File
/*
|
|
M68KITAB.c
|
|
|
|
Copyright (C) 2007 Paul C. Pratt
|
|
|
|
You can redistribute this file and/or modify it under the terms
|
|
of version 2 of the GNU General Public License as published by
|
|
the Free Software Foundation. You should have received a copy
|
|
of the license along with this file; see the file COPYING.
|
|
|
|
This file is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
license for more details.
|
|
*/
|
|
|
|
/*
|
|
Motorola 68K Instructions TABle
|
|
*/
|
|
|
|
#ifndef AllFiles
|
|
#include "SYSDEPNS.h"
|
|
#endif
|
|
|
|
#include "MYOSGLUE.h"
|
|
#include "EMCONFIG.h"
|
|
#include "GLOBGLUE.h"
|
|
|
|
#include "M68KITAB.h"
|
|
|
|
struct WorkR {
|
|
/* expected size : 8 bytes */
|
|
ui5b opcode;
|
|
ui5b opsize;
|
|
ui4r MainClass;
|
|
#if WantCycByPriOp
|
|
ui4r Cycles;
|
|
#endif
|
|
DecOpR DecOp;
|
|
};
|
|
typedef struct WorkR WorkR;
|
|
|
|
#define b76(p) ((p->opcode >> 6) & 3)
|
|
#define b8(p) ((p->opcode >> 8) & 1)
|
|
#define mode(p) ((p->opcode >> 3) & 7)
|
|
#define reg(p) (p->opcode & 7)
|
|
#define md6(p) ((p->opcode >> 6) & 7)
|
|
#define rg9(p) ((p->opcode >> 9) & 7)
|
|
|
|
enum {
|
|
kAddrValidAny,
|
|
kAddrValidData,
|
|
kAddrValidDataAlt,
|
|
kAddrValidControl,
|
|
kAddrValidControlAlt,
|
|
kAddrValidAltMem,
|
|
kAddrValidDataNoCn, /* no constants (immediate data) */
|
|
|
|
kNumAddrValids
|
|
};
|
|
|
|
#define kAddrValidMaskAny (1 << kAddrValidAny)
|
|
#define kAddrValidMaskData (1 << kAddrValidData)
|
|
#define kAddrValidMaskDataAlt (1 << kAddrValidDataAlt)
|
|
#define kAddrValidMaskControl (1 << kAddrValidControl)
|
|
#define kAddrValidMaskControlAlt (1 << kAddrValidControlAlt)
|
|
#define kAddrValidMaskAltMem (1 << kAddrValidAltMem)
|
|
#define kAddrValidMaskDataNoCn (1 << kAddrValidDataNoCn)
|
|
|
|
#define CheckInSet(v, m) (0 != ((1 << (v)) & (m)))
|
|
|
|
#define kMyAvgCycPerInstr (10 * kCycleScale + (40 * kCycleScale / 64))
|
|
|
|
LOCALFUNC ui3r GetAMdRegSz(WorkR *p)
|
|
{
|
|
ui3r CurAMd;
|
|
|
|
switch (p->opsize) {
|
|
case 1:
|
|
CurAMd = kAMdRegB;
|
|
break;
|
|
case 2:
|
|
default: /* keep compiler happy */
|
|
CurAMd = kAMdRegW;
|
|
break;
|
|
case 4:
|
|
CurAMd = kAMdRegL;
|
|
break;
|
|
}
|
|
|
|
return CurAMd;
|
|
}
|
|
|
|
LOCALFUNC ui3r GetAMdIndirectSz(WorkR *p)
|
|
{
|
|
ui3r CurAMd;
|
|
|
|
switch (p->opsize) {
|
|
case 1:
|
|
CurAMd = kAMdIndirectB;
|
|
break;
|
|
case 2:
|
|
default: /* keep compiler happy */
|
|
CurAMd = kAMdIndirectW;
|
|
break;
|
|
case 4:
|
|
CurAMd = kAMdIndirectL;
|
|
break;
|
|
}
|
|
|
|
return CurAMd;
|
|
}
|
|
|
|
#if WantCycByPriOp
|
|
LOCALFUNC ui4r OpEACalcCyc(WorkR *p, ui3r m, ui3r r)
|
|
{
|
|
ui4r v;
|
|
|
|
switch (m) {
|
|
case 0:
|
|
case 1:
|
|
v = 0;
|
|
break;
|
|
case 2:
|
|
v = ((4 == p->opsize)
|
|
? (8 * kCycleScale + 2 * RdAvgXtraCyc)
|
|
: (4 * kCycleScale + RdAvgXtraCyc));
|
|
break;
|
|
case 3:
|
|
v = ((4 == p->opsize)
|
|
? (8 * kCycleScale + 2 * RdAvgXtraCyc)
|
|
: (4 * kCycleScale + RdAvgXtraCyc));
|
|
break;
|
|
case 4:
|
|
v = ((4 == p->opsize)
|
|
? (10 * kCycleScale + 2 * RdAvgXtraCyc)
|
|
: (6 * kCycleScale + RdAvgXtraCyc));
|
|
break;
|
|
case 5:
|
|
v = ((4 == p->opsize)
|
|
? (12 * kCycleScale + 3 * RdAvgXtraCyc)
|
|
: (8 * kCycleScale + 2 * RdAvgXtraCyc));
|
|
break;
|
|
case 6:
|
|
v = ((4 == p->opsize)
|
|
? (14 * kCycleScale + 3 * RdAvgXtraCyc)
|
|
: (10 * kCycleScale + 2 * RdAvgXtraCyc));
|
|
break;
|
|
case 7:
|
|
switch (r) {
|
|
case 0:
|
|
v = ((4 == p->opsize)
|
|
? (12 * kCycleScale + 3 * RdAvgXtraCyc)
|
|
: (8 * kCycleScale + 2 * RdAvgXtraCyc));
|
|
break;
|
|
case 1:
|
|
v = ((4 == p->opsize)
|
|
? (16 * kCycleScale + 4 * RdAvgXtraCyc)
|
|
: (12 * kCycleScale + 3 * RdAvgXtraCyc));
|
|
break;
|
|
case 2:
|
|
v = ((4 == p->opsize)
|
|
? (12 * kCycleScale + 3 * RdAvgXtraCyc)
|
|
: (8 * kCycleScale + 2 * RdAvgXtraCyc));
|
|
break;
|
|
case 3:
|
|
v = ((4 == p->opsize)
|
|
? (14 * kCycleScale + 3 * RdAvgXtraCyc)
|
|
: (10 * kCycleScale + 2 * RdAvgXtraCyc));
|
|
break;
|
|
case 4:
|
|
v = ((4 == p->opsize)
|
|
? (8 * kCycleScale + 2 * RdAvgXtraCyc)
|
|
: (4 * kCycleScale + RdAvgXtraCyc));
|
|
break;
|
|
default:
|
|
v = 0;
|
|
break;
|
|
}
|
|
break;
|
|
default: /* keep compiler happy */
|
|
v = 0;
|
|
break;
|
|
}
|
|
|
|
return v;
|
|
}
|
|
#endif
|
|
|
|
#if WantCycByPriOp
|
|
LOCALFUNC ui4r OpEADestCalcCyc(WorkR *p, ui3r m, ui3r r)
|
|
{
|
|
ui4r v;
|
|
|
|
switch (m) {
|
|
case 0:
|
|
case 1:
|
|
v = 0;
|
|
break;
|
|
case 2:
|
|
v = ((4 == p->opsize)
|
|
? (8 * kCycleScale + 2 * WrAvgXtraCyc)
|
|
: (4 * kCycleScale + WrAvgXtraCyc));
|
|
break;
|
|
case 3:
|
|
v = ((4 == p->opsize)
|
|
? (8 * kCycleScale + 2 * WrAvgXtraCyc)
|
|
: (4 * kCycleScale + WrAvgXtraCyc));
|
|
break;
|
|
case 4:
|
|
v = ((4 == p->opsize)
|
|
? (8 * kCycleScale + 2 * WrAvgXtraCyc)
|
|
: (4 * kCycleScale + WrAvgXtraCyc));
|
|
break;
|
|
case 5:
|
|
v = ((4 == p->opsize)
|
|
? (12 * kCycleScale + RdAvgXtraCyc + 2 * WrAvgXtraCyc)
|
|
: (8 * kCycleScale + RdAvgXtraCyc + WrAvgXtraCyc));
|
|
break;
|
|
case 6:
|
|
v = ((4 == p->opsize)
|
|
? (14 * kCycleScale + RdAvgXtraCyc + 2 * WrAvgXtraCyc)
|
|
: (10 * kCycleScale + RdAvgXtraCyc + WrAvgXtraCyc));
|
|
break;
|
|
case 7:
|
|
switch (r) {
|
|
case 0:
|
|
v = ((4 == p->opsize)
|
|
? (12 * kCycleScale
|
|
+ RdAvgXtraCyc + 2 * WrAvgXtraCyc)
|
|
: (8 * kCycleScale
|
|
+ RdAvgXtraCyc + WrAvgXtraCyc));
|
|
break;
|
|
case 1:
|
|
v = ((4 == p->opsize)
|
|
? (16 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc + 2 * WrAvgXtraCyc)
|
|
: (12 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc + WrAvgXtraCyc));
|
|
break;
|
|
default:
|
|
v = 0;
|
|
break;
|
|
}
|
|
break;
|
|
default: /* keep compiler happy */
|
|
v = 0;
|
|
break;
|
|
}
|
|
|
|
return v;
|
|
}
|
|
#endif
|
|
|
|
LOCALPROC SetDcoArgFields(WorkR *p, blnr src,
|
|
ui3r CurAMd, ui3r CurArgDat)
|
|
{
|
|
if (src) {
|
|
p->DecOp.y.v[0].AMd = CurAMd;
|
|
p->DecOp.y.v[0].ArgDat = CurArgDat;
|
|
} else {
|
|
p->DecOp.y.v[1].AMd = CurAMd;
|
|
p->DecOp.y.v[1].ArgDat = CurArgDat;
|
|
}
|
|
}
|
|
|
|
LOCALFUNC blnr CheckValidAddrMode(WorkR *p,
|
|
ui3r m, ui3r r, ui3r v, blnr src)
|
|
{
|
|
ui3r CurAMd = 0; /* init to keep compiler happy */
|
|
ui3r CurArgDat = 0;
|
|
blnr IsOk;
|
|
|
|
switch (m) {
|
|
case 0:
|
|
CurAMd = GetAMdRegSz(p);
|
|
CurArgDat = r;
|
|
IsOk = CheckInSet(v,
|
|
kAddrValidMaskAny | kAddrValidMaskData
|
|
| kAddrValidMaskDataAlt | kAddrValidMaskDataNoCn);
|
|
break;
|
|
case 1:
|
|
CurAMd = GetAMdRegSz(p);
|
|
CurArgDat = r + 8;
|
|
IsOk = CheckInSet(v, kAddrValidMaskAny);
|
|
break;
|
|
case 2:
|
|
CurAMd = GetAMdIndirectSz(p);
|
|
CurArgDat = r + 8;
|
|
IsOk = CheckInSet(v,
|
|
kAddrValidMaskAny | kAddrValidMaskData
|
|
| kAddrValidMaskDataAlt | kAddrValidMaskControl
|
|
| kAddrValidMaskControlAlt | kAddrValidMaskAltMem
|
|
| kAddrValidMaskDataNoCn);
|
|
break;
|
|
case 3:
|
|
switch (p->opsize) {
|
|
case 1:
|
|
if (7 == r) {
|
|
CurAMd = kAMdAPosInc7B;
|
|
} else {
|
|
CurAMd = kAMdAPosIncB;
|
|
}
|
|
break;
|
|
case 2:
|
|
default: /* keep compiler happy */
|
|
CurAMd = kAMdAPosIncW;
|
|
break;
|
|
case 4:
|
|
CurAMd = kAMdAPosIncL;
|
|
break;
|
|
}
|
|
CurArgDat = r + 8;
|
|
IsOk = CheckInSet(v,
|
|
kAddrValidMaskAny | kAddrValidMaskData
|
|
| kAddrValidMaskDataAlt | kAddrValidMaskAltMem
|
|
| kAddrValidMaskDataNoCn);
|
|
break;
|
|
case 4:
|
|
switch (p->opsize) {
|
|
case 1:
|
|
if (7 == r) {
|
|
CurAMd = kAMdAPreDec7B;
|
|
} else {
|
|
CurAMd = kAMdAPreDecB;
|
|
}
|
|
break;
|
|
case 2:
|
|
default: /* keep compiler happy */
|
|
CurAMd = kAMdAPreDecW;
|
|
break;
|
|
case 4:
|
|
CurAMd = kAMdAPreDecL;
|
|
break;
|
|
}
|
|
CurArgDat = r + 8;
|
|
IsOk = CheckInSet(v,
|
|
kAddrValidMaskAny | kAddrValidMaskData
|
|
| kAddrValidMaskDataAlt | kAddrValidMaskAltMem
|
|
| kAddrValidMaskDataNoCn);
|
|
break;
|
|
case 5:
|
|
switch (p->opsize) {
|
|
case 1:
|
|
CurAMd = kAMdADispB;
|
|
break;
|
|
case 2:
|
|
default: /* keep compiler happy */
|
|
CurAMd = kAMdADispW;
|
|
break;
|
|
case 4:
|
|
CurAMd = kAMdADispL;
|
|
break;
|
|
}
|
|
CurArgDat = r + 8;
|
|
IsOk = CheckInSet(v,
|
|
kAddrValidMaskAny | kAddrValidMaskData
|
|
| kAddrValidMaskDataAlt | kAddrValidMaskControl
|
|
| kAddrValidMaskControlAlt | kAddrValidMaskAltMem
|
|
| kAddrValidMaskDataNoCn);
|
|
break;
|
|
case 6:
|
|
switch (p->opsize) {
|
|
case 1:
|
|
CurAMd = kAMdAIndexB;
|
|
break;
|
|
case 2:
|
|
default: /* keep compiler happy */
|
|
CurAMd = kAMdAIndexW;
|
|
break;
|
|
case 4:
|
|
CurAMd = kAMdAIndexL;
|
|
break;
|
|
}
|
|
CurArgDat = r + 8;
|
|
IsOk = CheckInSet(v,
|
|
kAddrValidMaskAny | kAddrValidMaskData
|
|
| kAddrValidMaskDataAlt | kAddrValidMaskControl
|
|
| kAddrValidMaskControlAlt | kAddrValidMaskAltMem
|
|
| kAddrValidMaskDataNoCn);
|
|
break;
|
|
case 7:
|
|
switch (r) {
|
|
case 0:
|
|
switch (p->opsize) {
|
|
case 1:
|
|
CurAMd = kAMdAbsWB;
|
|
break;
|
|
case 2:
|
|
default: /* keep compiler happy */
|
|
CurAMd = kAMdAbsWW;
|
|
break;
|
|
case 4:
|
|
CurAMd = kAMdAbsWL;
|
|
break;
|
|
}
|
|
IsOk = CheckInSet(v,
|
|
kAddrValidMaskAny | kAddrValidMaskData
|
|
| kAddrValidMaskDataAlt
|
|
| kAddrValidMaskControl
|
|
| kAddrValidMaskControlAlt
|
|
| kAddrValidMaskAltMem
|
|
| kAddrValidMaskDataNoCn);
|
|
break;
|
|
case 1:
|
|
switch (p->opsize) {
|
|
case 1:
|
|
CurAMd = kAMdAbsLB;
|
|
break;
|
|
case 2:
|
|
default: /* keep compiler happy */
|
|
CurAMd = kAMdAbsLW;
|
|
break;
|
|
case 4:
|
|
CurAMd = kAMdAbsLL;
|
|
break;
|
|
}
|
|
IsOk = CheckInSet(v,
|
|
kAddrValidMaskAny | kAddrValidMaskData
|
|
| kAddrValidMaskDataAlt
|
|
| kAddrValidMaskControl
|
|
| kAddrValidMaskControlAlt
|
|
| kAddrValidMaskAltMem
|
|
| kAddrValidMaskDataNoCn);
|
|
break;
|
|
case 2:
|
|
switch (p->opsize) {
|
|
case 1:
|
|
CurAMd = kAMdPCDispB;
|
|
break;
|
|
case 2:
|
|
default: /* keep compiler happy */
|
|
CurAMd = kAMdPCDispW;
|
|
break;
|
|
case 4:
|
|
CurAMd = kAMdPCDispL;
|
|
break;
|
|
}
|
|
IsOk = CheckInSet(v,
|
|
kAddrValidMaskAny | kAddrValidMaskData
|
|
| kAddrValidMaskControl
|
|
| kAddrValidMaskDataNoCn);
|
|
break;
|
|
case 3:
|
|
switch (p->opsize) {
|
|
case 1:
|
|
CurAMd = kAMdPCIndexB;
|
|
break;
|
|
case 2:
|
|
default: /* keep compiler happy */
|
|
CurAMd = kAMdPCIndexW;
|
|
break;
|
|
case 4:
|
|
CurAMd = kAMdPCIndexL;
|
|
break;
|
|
}
|
|
IsOk = CheckInSet(v,
|
|
kAddrValidMaskAny | kAddrValidMaskData
|
|
| kAddrValidMaskControl
|
|
| kAddrValidMaskDataNoCn);
|
|
break;
|
|
case 4:
|
|
switch (p->opsize) {
|
|
case 1:
|
|
CurAMd = kAMdImmedB;
|
|
break;
|
|
case 2:
|
|
default: /* keep compiler happy */
|
|
CurAMd = kAMdImmedW;
|
|
break;
|
|
case 4:
|
|
CurAMd = kAMdImmedL;
|
|
break;
|
|
}
|
|
IsOk = CheckInSet(v,
|
|
kAddrValidMaskAny | kAddrValidMaskData);
|
|
break;
|
|
default:
|
|
IsOk = falseblnr;
|
|
break;
|
|
}
|
|
break;
|
|
default: /* keep compiler happy */
|
|
IsOk = falseblnr;
|
|
break;
|
|
}
|
|
|
|
if (IsOk) {
|
|
SetDcoArgFields(p, src, CurAMd, CurArgDat);
|
|
}
|
|
|
|
return IsOk;
|
|
}
|
|
|
|
#if WantCycByPriOp
|
|
LOCALFUNC blnr LeaPeaEACalcCyc(WorkR *p, ui3r m, ui3r r)
|
|
{
|
|
ui4r v;
|
|
|
|
UnusedParam(p);
|
|
switch (m) {
|
|
case 2:
|
|
v = 0;
|
|
break;
|
|
case 5:
|
|
v = (4 * kCycleScale + RdAvgXtraCyc);
|
|
break;
|
|
case 6:
|
|
v = (8 * kCycleScale + RdAvgXtraCyc);
|
|
break;
|
|
case 7:
|
|
switch (r) {
|
|
case 0:
|
|
v = (4 * kCycleScale + RdAvgXtraCyc);
|
|
break;
|
|
case 1:
|
|
v = (8 * kCycleScale + 2 * RdAvgXtraCyc);
|
|
break;
|
|
case 2:
|
|
v = (4 * kCycleScale + RdAvgXtraCyc);
|
|
break;
|
|
case 3:
|
|
v = (8 * kCycleScale + RdAvgXtraCyc);
|
|
break;
|
|
default:
|
|
v = 0;
|
|
break;
|
|
}
|
|
break;
|
|
default: /* keep compiler happy */
|
|
v = 0;
|
|
break;
|
|
}
|
|
|
|
return v;
|
|
}
|
|
#endif
|
|
|
|
LOCALFUNC blnr IsValidAddrMode(WorkR *p)
|
|
{
|
|
return CheckValidAddrMode(p,
|
|
mode(p), reg(p), kAddrValidAny, falseblnr);
|
|
}
|
|
|
|
LOCALFUNC blnr CheckDataAltAddrMode(WorkR *p)
|
|
{
|
|
return CheckValidAddrMode(p,
|
|
mode(p), reg(p), kAddrValidDataAlt, falseblnr);
|
|
}
|
|
|
|
LOCALFUNC blnr CheckDataAddrMode(WorkR *p)
|
|
{
|
|
return CheckValidAddrMode(p,
|
|
mode(p), reg(p), kAddrValidData, falseblnr);
|
|
}
|
|
|
|
LOCALFUNC blnr CheckControlAddrMode(WorkR *p)
|
|
{
|
|
return CheckValidAddrMode(p,
|
|
mode(p), reg(p), kAddrValidControl, falseblnr);
|
|
}
|
|
|
|
LOCALFUNC blnr CheckControlAltAddrMode(WorkR *p)
|
|
{
|
|
return CheckValidAddrMode(p,
|
|
mode(p), reg(p), kAddrValidControlAlt, falseblnr);
|
|
}
|
|
|
|
LOCALFUNC blnr CheckAltMemAddrMode(WorkR *p)
|
|
{
|
|
return CheckValidAddrMode(p,
|
|
mode(p), reg(p), kAddrValidAltMem, falseblnr);
|
|
}
|
|
|
|
LOCALPROC FindOpSizeFromb76(WorkR *p)
|
|
{
|
|
p->opsize = 1 << b76(p);
|
|
#if 0
|
|
switch (b76(p)) {
|
|
case 0 :
|
|
p->opsize = 1;
|
|
break;
|
|
case 1 :
|
|
p->opsize = 2;
|
|
break;
|
|
case 2 :
|
|
p->opsize = 4;
|
|
break;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
LOCALFUNC ui3r OpSizeOffset(WorkR *p)
|
|
{
|
|
ui3r v;
|
|
|
|
switch (p->opsize) {
|
|
case 1 :
|
|
v = 0;
|
|
break;
|
|
case 2 :
|
|
v = 1;
|
|
break;
|
|
case 4 :
|
|
default :
|
|
v = 2;
|
|
break;
|
|
}
|
|
|
|
return v;
|
|
}
|
|
|
|
|
|
LOCALFUNC ui5r octdat(ui5r x)
|
|
{
|
|
if (x == 0) {
|
|
return 8;
|
|
} else {
|
|
return x;
|
|
}
|
|
}
|
|
|
|
LOCALPROCUSEDONCE DeCode0(WorkR *p)
|
|
{
|
|
if (b8(p) == 1) {
|
|
if (mode(p) == 1) {
|
|
/* MoveP 0000ddd1mm001aaa */
|
|
#if WantCycByPriOp
|
|
switch (b76(p)) {
|
|
case 0:
|
|
p->Cycles = (16 * kCycleScale + 4 * RdAvgXtraCyc);
|
|
break;
|
|
case 1:
|
|
p->Cycles = (24 * kCycleScale + 6 * RdAvgXtraCyc);
|
|
break;
|
|
case 2:
|
|
p->Cycles = (16 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc + 2 * WrAvgXtraCyc);
|
|
break;
|
|
case 3:
|
|
default: /* keep compiler happy */
|
|
p->Cycles = (24 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc + 4 * WrAvgXtraCyc);
|
|
break;
|
|
}
|
|
#endif
|
|
if (CheckValidAddrMode(p, 1, reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
p->MainClass = kIKindMoveP0 + b76(p);
|
|
}
|
|
} else {
|
|
/* dynamic bit, Opcode = 0000ddd1ttmmmrrr */
|
|
if (mode(p) == 0) {
|
|
p->opsize = 4;
|
|
#if WantCycByPriOp
|
|
switch (b76(p)) {
|
|
case 0: /* BTst */
|
|
p->Cycles = (6 * kCycleScale + RdAvgXtraCyc);
|
|
break;
|
|
case 1: /* BChg */
|
|
p->Cycles = (8 * kCycleScale + RdAvgXtraCyc);
|
|
break;
|
|
case 2: /* BClr */
|
|
p->Cycles = (10 * kCycleScale + RdAvgXtraCyc);
|
|
break;
|
|
case 3: /* BSet */
|
|
p->Cycles = (8 * kCycleScale + RdAvgXtraCyc);
|
|
break;
|
|
}
|
|
#endif
|
|
p->MainClass = kIKindBTstL + b76(p);
|
|
SetDcoArgFields(p, trueblnr, kAMdRegL, rg9(p));
|
|
SetDcoArgFields(p, falseblnr, kAMdRegL, reg(p));
|
|
} else {
|
|
p->opsize = 1;
|
|
p->MainClass = kIKindBTstB + b76(p);
|
|
SetDcoArgFields(p, trueblnr, kAMdRegB, rg9(p));
|
|
if (b76(p) == 0) { /* BTst */
|
|
if (CheckDataAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
}
|
|
} else {
|
|
if (CheckDataAltAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
p->Cycles = (8 * kCycleScale
|
|
+ RdAvgXtraCyc + WrAvgXtraCyc);
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (rg9(p) == 4) {
|
|
/* static bit 00001010ssmmmrrr */
|
|
if (mode(p) == 0) {
|
|
p->opsize = 4;
|
|
#if WantCycByPriOp
|
|
switch (b76(p)) {
|
|
case 0: /* BTst */
|
|
p->Cycles =
|
|
(10 * kCycleScale + 2 * RdAvgXtraCyc);
|
|
break;
|
|
case 1: /* BChg */
|
|
p->Cycles =
|
|
(12 * kCycleScale + 2 * RdAvgXtraCyc);
|
|
break;
|
|
case 2: /* BClr */
|
|
p->Cycles =
|
|
(14 * kCycleScale + 2 * RdAvgXtraCyc);
|
|
break;
|
|
case 3: /* BSet */
|
|
p->Cycles =
|
|
(12 * kCycleScale + 2 * RdAvgXtraCyc);
|
|
break;
|
|
}
|
|
#endif
|
|
SetDcoArgFields(p, trueblnr, kAMdImmedB, 0);
|
|
SetDcoArgFields(p, falseblnr, kAMdRegL, reg(p));
|
|
p->MainClass = kIKindBTstL + b76(p);
|
|
} else {
|
|
p->opsize = 1;
|
|
SetDcoArgFields(p, trueblnr, kAMdImmedB, 0);
|
|
p->MainClass = kIKindBTstB + b76(p);
|
|
if (b76(p) == 0) { /* BTst */
|
|
if (CheckValidAddrMode(p,
|
|
mode(p), reg(p), kAddrValidDataNoCn, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
p->Cycles =
|
|
(8 * kCycleScale + 2 * RdAvgXtraCyc);
|
|
p->Cycles +=
|
|
OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
}
|
|
} else {
|
|
if (CheckDataAltAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
p->Cycles = (12 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc + WrAvgXtraCyc);
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
} else
|
|
if (b76(p) == 3) {
|
|
#if Use68020
|
|
if (rg9(p) < 3) {
|
|
/* CHK2 or CMP2 00000ss011mmmrrr */
|
|
switch ((p->opcode >> 9) & 3) {
|
|
case 0 :
|
|
p->opsize = 1;
|
|
break;
|
|
case 1 :
|
|
p->opsize = 2;
|
|
break;
|
|
case 2 :
|
|
p->opsize = 4;
|
|
break;
|
|
}
|
|
p->DecOp.y.v[0].ArgDat = p->opsize;
|
|
/* size */
|
|
if (CheckControlAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindCHK2orCMP2;
|
|
}
|
|
} else
|
|
if (rg9(p) >= 5) {
|
|
switch ((p->opcode >> 9) & 3) {
|
|
case 1 :
|
|
p->opsize = 1;
|
|
break;
|
|
case 2 :
|
|
p->opsize = 2;
|
|
break;
|
|
case 3 :
|
|
p->opsize = 4;
|
|
break;
|
|
}
|
|
p->DecOp.y.v[0].ArgDat = p->opsize;
|
|
if ((mode(p) == 7) && (reg(p) == 4)) {
|
|
/* CAS2 00001ss011111100 */
|
|
p->MainClass = kIKindCAS2;
|
|
} else {
|
|
/* CAS 00001ss011mmmrrr */
|
|
if (CheckDataAltAddrMode(p)) {
|
|
p->MainClass = kIKindCAS;
|
|
}
|
|
}
|
|
} else
|
|
if (rg9(p) == 3) {
|
|
/* CALLM or RTM 0000011011mmmrrr */
|
|
p->MainClass = kIKindCallMorRtm;
|
|
} else
|
|
#endif
|
|
{
|
|
p->MainClass = kIKindIllegal;
|
|
}
|
|
} else
|
|
if (rg9(p) == 6) {
|
|
/* CMPI 00001100ssmmmrrr */
|
|
#if 0
|
|
if (CheckDataAltAddrMode(p)) {
|
|
p->MainClass = kIKindCmpI;
|
|
}
|
|
#endif
|
|
FindOpSizeFromb76(p);
|
|
if (CheckValidAddrMode(p, 7, 4, kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p,
|
|
mode(p), reg(p), kAddrValidDataNoCn, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
if (0 == mode(p)) {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (14 * kCycleScale + 3 * RdAvgXtraCyc)
|
|
: (8 * kCycleScale + 2 * RdAvgXtraCyc);
|
|
} else {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (12 * kCycleScale + 3 * RdAvgXtraCyc)
|
|
: (8 * kCycleScale + 2 * RdAvgXtraCyc);
|
|
}
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindCmpB + OpSizeOffset(p);
|
|
}
|
|
} else if (rg9(p) == 7) {
|
|
#if Use68020
|
|
/* MoveS 00001110ssmmmrrr */
|
|
FindOpSizeFromb76(p);
|
|
p->DecOp.y.v[0].ArgDat = p->opsize;
|
|
if (CheckAltMemAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindMoveS;
|
|
}
|
|
#else
|
|
p->MainClass = kIKindIllegal;
|
|
#endif
|
|
} else {
|
|
if ((mode(p) == 7) && (reg(p) == 4)) {
|
|
switch (rg9(p)) {
|
|
case 0:
|
|
#if WantCycByPriOp
|
|
p->Cycles =
|
|
(20 * kCycleScale + 3 * RdAvgXtraCyc);
|
|
#endif
|
|
p->MainClass = (0 != b76(p))
|
|
? kIKindOrISR : kIKindOrICCR;
|
|
break;
|
|
case 1:
|
|
#if WantCycByPriOp
|
|
p->Cycles =
|
|
(20 * kCycleScale + 3 * RdAvgXtraCyc);
|
|
#endif
|
|
p->MainClass = (0 != b76(p))
|
|
? kIKindAndISR : kIKindAndICCR;
|
|
break;
|
|
case 5:
|
|
#if WantCycByPriOp
|
|
p->Cycles =
|
|
(20 * kCycleScale + 3 * RdAvgXtraCyc);
|
|
#endif
|
|
p->MainClass = (0 != b76(p))
|
|
? kIKindEorISR : kIKindEorICCR;
|
|
break;
|
|
default:
|
|
p->MainClass = kIKindIllegal;
|
|
break;
|
|
}
|
|
} else {
|
|
switch (rg9(p)) {
|
|
case 0:
|
|
#if 0
|
|
if (CheckDataAltAddrMode(p)) {
|
|
p->MainClass = kIKindOrI;
|
|
}
|
|
#endif
|
|
FindOpSizeFromb76(p);
|
|
if (CheckValidAddrMode(p, 7, 4,
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidDataAlt, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
if (0 != mode(p)) {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (20 * kCycleScale
|
|
+ 3 * RdAvgXtraCyc
|
|
+ 2 * WrAvgXtraCyc)
|
|
: (12 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc
|
|
+ WrAvgXtraCyc);
|
|
} else {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (16 * kCycleScale
|
|
+ 3 * RdAvgXtraCyc)
|
|
: (8 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc);
|
|
}
|
|
p->Cycles +=
|
|
OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindOrI;
|
|
}
|
|
break;
|
|
case 1:
|
|
#if 0
|
|
if (CheckDataAltAddrMode(p)) {
|
|
p->MainClass = kIKindAndI;
|
|
}
|
|
#endif
|
|
FindOpSizeFromb76(p);
|
|
if (CheckValidAddrMode(p, 7, 4,
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidDataAlt, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
if (0 != mode(p)) {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (20 * kCycleScale
|
|
+ 3 * RdAvgXtraCyc
|
|
+ 2 * WrAvgXtraCyc)
|
|
: (12 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc
|
|
+ WrAvgXtraCyc);
|
|
} else {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (14 * kCycleScale
|
|
+ 3 * RdAvgXtraCyc)
|
|
: (8 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc);
|
|
}
|
|
p->Cycles +=
|
|
OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindAndI;
|
|
}
|
|
break;
|
|
case 2:
|
|
#if 0
|
|
if (CheckDataAltAddrMode(p)) {
|
|
p->MainClass = kIKindSubI;
|
|
}
|
|
#endif
|
|
FindOpSizeFromb76(p);
|
|
if (CheckValidAddrMode(p, 7, 4,
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidDataAlt, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
if (0 != mode(p)) {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (20 * kCycleScale
|
|
+ 3 * RdAvgXtraCyc
|
|
+ 2 * WrAvgXtraCyc)
|
|
: (12 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc
|
|
+ WrAvgXtraCyc);
|
|
} else {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (16 * kCycleScale
|
|
+ 3 * RdAvgXtraCyc)
|
|
: (8 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc);
|
|
}
|
|
p->Cycles +=
|
|
OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindSubB + OpSizeOffset(p);
|
|
}
|
|
break;
|
|
case 3:
|
|
#if 0
|
|
if (CheckDataAltAddrMode(p)) {
|
|
p->MainClass = kIKindAddI;
|
|
}
|
|
#endif
|
|
FindOpSizeFromb76(p);
|
|
if (CheckValidAddrMode(p, 7, 4,
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidDataAlt, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
if (0 != mode(p)) {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (20 * kCycleScale
|
|
+ 3 * RdAvgXtraCyc
|
|
+ 2 * WrAvgXtraCyc)
|
|
: (12 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc
|
|
+ WrAvgXtraCyc);
|
|
} else {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (16 * kCycleScale
|
|
+ 3 * RdAvgXtraCyc)
|
|
: (8 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc);
|
|
}
|
|
p->Cycles +=
|
|
OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindAddB + OpSizeOffset(p);
|
|
}
|
|
break;
|
|
case 5:
|
|
#if 0
|
|
if (CheckDataAltAddrMode(p)) {
|
|
p->MainClass = kIKindEorI;
|
|
}
|
|
#endif
|
|
FindOpSizeFromb76(p);
|
|
if (CheckValidAddrMode(p, 7, 4,
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidDataAlt, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
if (0 != mode(p)) {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (20 * kCycleScale
|
|
+ 3 * RdAvgXtraCyc
|
|
+ 2 * WrAvgXtraCyc)
|
|
: (12 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc
|
|
+ WrAvgXtraCyc);
|
|
} else {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (16 * kCycleScale
|
|
+ 3 * RdAvgXtraCyc)
|
|
: (8 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc);
|
|
}
|
|
p->Cycles +=
|
|
OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindEorI;
|
|
}
|
|
break;
|
|
default:
|
|
/* for compiler. should be 0, 1, 2, 3, or 5 */
|
|
p->MainClass = kIKindIllegal;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
LOCALPROCUSEDONCE DeCode1(WorkR *p)
|
|
{
|
|
p->opsize = 1;
|
|
if (md6(p) == 1) { /* MOVEA */
|
|
p->MainClass = kIKindIllegal;
|
|
} else if (mode(p) == 1) {
|
|
/* not allowed for byte sized move */
|
|
p->MainClass = kIKindIllegal;
|
|
} else {
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, md6(p), rg9(p),
|
|
kAddrValidDataAlt, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
p->Cycles += OpEADestCalcCyc(p, md6(p), rg9(p));
|
|
#endif
|
|
p->MainClass = kIKindMoveB;
|
|
}
|
|
}
|
|
}
|
|
|
|
LOCALPROCUSEDONCE DeCode2(WorkR *p)
|
|
{
|
|
p->opsize = 4;
|
|
if (md6(p) == 1) { /* MOVEA */
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, 1, rg9(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindMoveAL;
|
|
p->DecOp.y.v[1].ArgDat = rg9(p);
|
|
}
|
|
} else {
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, md6(p), rg9(p),
|
|
kAddrValidDataAlt, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
p->Cycles += OpEADestCalcCyc(p, md6(p), rg9(p));
|
|
#endif
|
|
p->MainClass = kIKindMoveL;
|
|
}
|
|
}
|
|
}
|
|
|
|
LOCALPROCUSEDONCE DeCode3(WorkR *p)
|
|
{
|
|
p->opsize = 2;
|
|
if (md6(p) == 1) { /* MOVEA */
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, 1, rg9(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindMoveAW;
|
|
p->DecOp.y.v[1].ArgDat = rg9(p);
|
|
}
|
|
} else {
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, md6(p), rg9(p),
|
|
kAddrValidDataAlt, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
p->Cycles += OpEADestCalcCyc(p, md6(p), rg9(p));
|
|
#endif
|
|
p->MainClass = kIKindMoveW;
|
|
}
|
|
}
|
|
}
|
|
|
|
#if WantCycByPriOp
|
|
|
|
#if WantCloserCyc
|
|
#define MoveAvgN 0
|
|
#else
|
|
#define MoveAvgN 3
|
|
#endif
|
|
|
|
LOCALFUNC ui4r MoveMEACalcCyc(WorkR *p, ui3r m, ui3r r)
|
|
{
|
|
ui4r v;
|
|
|
|
UnusedParam(p);
|
|
switch (m) {
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
v = (8 * kCycleScale + 2 * RdAvgXtraCyc);
|
|
break;
|
|
case 5:
|
|
v = (12 * kCycleScale + 3 * RdAvgXtraCyc);
|
|
break;
|
|
case 6:
|
|
v = (14 * kCycleScale + 3 * RdAvgXtraCyc);
|
|
break;
|
|
case 7:
|
|
switch (r) {
|
|
case 0:
|
|
v = (12 * kCycleScale + 3 * RdAvgXtraCyc);
|
|
break;
|
|
case 1:
|
|
v = (16 * kCycleScale + 4 * RdAvgXtraCyc);
|
|
break;
|
|
default:
|
|
v = 0;
|
|
break;
|
|
}
|
|
break;
|
|
default: /* keep compiler happy */
|
|
v = 0;
|
|
break;
|
|
}
|
|
|
|
return v;
|
|
}
|
|
|
|
#endif
|
|
|
|
LOCALPROCUSEDONCE DeCode4(WorkR *p)
|
|
{
|
|
if (b8(p) != 0) {
|
|
switch (b76(p)) {
|
|
case 0:
|
|
#if Use68020
|
|
/* Chk.L 0100ddd100mmmrrr */
|
|
p->opsize = 4;
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidData, falseblnr))
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, trueblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindChkL;
|
|
}
|
|
#else
|
|
p->MainClass = kIKindIllegal;
|
|
#endif
|
|
break;
|
|
case 1:
|
|
p->MainClass = kIKindIllegal;
|
|
break;
|
|
case 2:
|
|
/* Chk.W 0100ddd110mmmrrr */
|
|
p->opsize = 2;
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidData, falseblnr))
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, trueblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
p->Cycles = (10 * kCycleScale + RdAvgXtraCyc);
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindChkW;
|
|
}
|
|
break;
|
|
case 3:
|
|
default: /* keep compiler happy */
|
|
#if Use68020
|
|
if ((0 == mode(p)) && (4 == rg9(p))) {
|
|
/* EXTB.L */
|
|
SetDcoArgFields(p, falseblnr,
|
|
kAMdRegL, reg(p));
|
|
p->MainClass = kIKindEXTBL;
|
|
} else
|
|
#endif
|
|
{
|
|
/* Lea 0100aaa111mmmrrr */
|
|
if (CheckControlAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
|
|
p->Cycles +=
|
|
LeaPeaEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindLea;
|
|
p->DecOp.y.v[0].ArgDat = rg9(p);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
} else {
|
|
switch (rg9(p)) {
|
|
case 0:
|
|
if (b76(p) != 3) {
|
|
/* NegX 01000000ssmmmrrr */
|
|
FindOpSizeFromb76(p);
|
|
if (CheckDataAltAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
if (0 != mode(p)) {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (12 * kCycleScale
|
|
+ RdAvgXtraCyc + 2 * WrAvgXtraCyc)
|
|
: (8 * kCycleScale
|
|
+ RdAvgXtraCyc + WrAvgXtraCyc);
|
|
} else {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (6 * kCycleScale + RdAvgXtraCyc)
|
|
: (4 * kCycleScale + RdAvgXtraCyc);
|
|
}
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindNegXB + OpSizeOffset(p);
|
|
}
|
|
} else {
|
|
#if Use68020
|
|
/* reference seems incorrect to say not for 68000 */
|
|
#endif
|
|
/* Move from SR 0100000011mmmrrr */
|
|
p->opsize = 2;
|
|
if (CheckDataAltAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
p->Cycles =
|
|
(12 * kCycleScale + 2 * RdAvgXtraCyc);
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindMoveSREa;
|
|
}
|
|
}
|
|
break;
|
|
case 1:
|
|
if (b76(p) != 3) {
|
|
/* Clr 01000010ssmmmrrr */
|
|
FindOpSizeFromb76(p);
|
|
if (CheckDataAltAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
if (0 != mode(p)) {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (12 * kCycleScale
|
|
+ RdAvgXtraCyc + 2 * WrAvgXtraCyc)
|
|
: (8 * kCycleScale
|
|
+ RdAvgXtraCyc + WrAvgXtraCyc);
|
|
} else {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (6 * kCycleScale + RdAvgXtraCyc)
|
|
: (4 * kCycleScale + RdAvgXtraCyc);
|
|
}
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindClr;
|
|
}
|
|
} else {
|
|
#if Use68020
|
|
/* Move from CCR 0100001011mmmrrr */
|
|
p->opsize = 2;
|
|
if (CheckDataAltAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindMoveCCREa;
|
|
}
|
|
#else
|
|
p->MainClass = kIKindIllegal;
|
|
#endif
|
|
}
|
|
break;
|
|
case 2:
|
|
if (b76(p) != 3) {
|
|
/* Neg 01000100ssmmmrrr */
|
|
FindOpSizeFromb76(p);
|
|
if (CheckDataAltAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
if (0 != mode(p)) {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (12 * kCycleScale
|
|
+ RdAvgXtraCyc + 2 * WrAvgXtraCyc)
|
|
: (8 * kCycleScale
|
|
+ RdAvgXtraCyc + WrAvgXtraCyc);
|
|
} else {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (6 * kCycleScale + RdAvgXtraCyc)
|
|
: (4 * kCycleScale + RdAvgXtraCyc);
|
|
}
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindNegB + OpSizeOffset(p);
|
|
}
|
|
} else {
|
|
/* Move to CCR 0100010011mmmrrr */
|
|
p->opsize = 2;
|
|
if (CheckDataAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
p->Cycles = (12 * kCycleScale + RdAvgXtraCyc);
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindMoveEaCCR;
|
|
}
|
|
}
|
|
break;
|
|
case 3:
|
|
if (b76(p) != 3) {
|
|
/* Not 01000110ssmmmrrr */
|
|
FindOpSizeFromb76(p);
|
|
if (CheckDataAltAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
if (0 != mode(p)) {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (12 * kCycleScale
|
|
+ RdAvgXtraCyc + 2 * WrAvgXtraCyc)
|
|
: (8 * kCycleScale
|
|
+ RdAvgXtraCyc + WrAvgXtraCyc);
|
|
} else {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (6 * kCycleScale + RdAvgXtraCyc)
|
|
: (4 * kCycleScale + RdAvgXtraCyc);
|
|
}
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindNot;
|
|
}
|
|
} else {
|
|
/* Move from SR 0100011011mmmrrr */
|
|
p->opsize = 2;
|
|
if (CheckDataAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
if (0 != mode(p)) {
|
|
p->Cycles = (8 * kCycleScale
|
|
+ RdAvgXtraCyc + WrAvgXtraCyc);
|
|
} else {
|
|
p->Cycles =
|
|
(6 * kCycleScale + RdAvgXtraCyc);
|
|
}
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindMoveEaSR;
|
|
}
|
|
}
|
|
break;
|
|
case 4:
|
|
switch (b76(p)) {
|
|
case 0:
|
|
#if Use68020
|
|
if (mode(p) == 1) {
|
|
/* Link.L 0100100000001rrr */
|
|
SetDcoArgFields(p, falseblnr,
|
|
kAMdRegL, reg(p) + 8);
|
|
p->MainClass = kIKindLinkL;
|
|
} else
|
|
#endif
|
|
{
|
|
/* Nbcd 0100100000mmmrrr */
|
|
p->opsize = 1;
|
|
if (CheckDataAltAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
if (0 != mode(p)) {
|
|
p->Cycles = (8 * kCycleScale
|
|
+ RdAvgXtraCyc + WrAvgXtraCyc);
|
|
} else {
|
|
p->Cycles = (6 * kCycleScale
|
|
+ RdAvgXtraCyc);
|
|
}
|
|
p->Cycles +=
|
|
OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindNbcd;
|
|
}
|
|
}
|
|
break;
|
|
case 1:
|
|
if (mode(p) == 0) {
|
|
/* Swap 0100100001000rrr */
|
|
#if WantCycByPriOp
|
|
p->Cycles =
|
|
(4 * kCycleScale + RdAvgXtraCyc);
|
|
#endif
|
|
p->MainClass = kIKindSwap;
|
|
SetDcoArgFields(p, falseblnr,
|
|
kAMdRegL, reg(p));
|
|
} else
|
|
#if Use68020
|
|
if (mode(p) == 1) {
|
|
p->MainClass = kIKindBkpt;
|
|
} else
|
|
#endif
|
|
{
|
|
/* PEA 0100100001mmmrrr */
|
|
if (CheckControlAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
p->Cycles = (12 * kCycleScale
|
|
+ RdAvgXtraCyc
|
|
+ 2 * WrAvgXtraCyc);
|
|
p->Cycles +=
|
|
LeaPeaEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindPEA;
|
|
}
|
|
}
|
|
break;
|
|
case 2:
|
|
if (mode(p) == 0) {
|
|
/* EXT.W */
|
|
#if WantCycByPriOp
|
|
p->Cycles =
|
|
(4 * kCycleScale + RdAvgXtraCyc);
|
|
#endif
|
|
SetDcoArgFields(p, falseblnr,
|
|
kAMdRegW, reg(p));
|
|
p->MainClass = kIKindEXTW;
|
|
} else {
|
|
/* MOVEM reg to mem 01001d001ssmmmrrr */
|
|
p->opsize = 2;
|
|
if (mode(p) == 4) {
|
|
#if WantCycByPriOp
|
|
p->Cycles =
|
|
MoveMEACalcCyc(p, mode(p), reg(p));
|
|
p->Cycles += MoveAvgN * 4 * kCycleScale
|
|
+ MoveAvgN * WrAvgXtraCyc;
|
|
#endif
|
|
SetDcoArgFields(p, falseblnr,
|
|
kAMdAPreDecL, reg(p) + 8);
|
|
p->MainClass = kIKindMOVEMRmMW;
|
|
} else {
|
|
if (CheckControlAltAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
p->Cycles = MoveMEACalcCyc(p,
|
|
mode(p), reg(p));
|
|
p->Cycles +=
|
|
MoveAvgN * 4 * kCycleScale
|
|
+ MoveAvgN * WrAvgXtraCyc;
|
|
#endif
|
|
p->MainClass = kIKindMOVEMrmW;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case 3:
|
|
default: /* keep compiler happy */
|
|
if (mode(p) == 0) {
|
|
/* EXT.L */
|
|
#if WantCycByPriOp
|
|
p->Cycles =
|
|
(4 * kCycleScale + RdAvgXtraCyc);
|
|
#endif
|
|
SetDcoArgFields(p, falseblnr,
|
|
kAMdRegL, reg(p));
|
|
p->MainClass = kIKindEXTL;
|
|
} else {
|
|
/* MOVEM reg to mem 01001d001ssmmmrrr */
|
|
#if WantCycByPriOp
|
|
p->Cycles = MoveMEACalcCyc(p,
|
|
mode(p), reg(p));
|
|
p->Cycles += MoveAvgN * 8 * kCycleScale
|
|
+ MoveAvgN * 2 * WrAvgXtraCyc;
|
|
#endif
|
|
p->opsize = 4;
|
|
if (mode(p) == 4) {
|
|
SetDcoArgFields(p, falseblnr,
|
|
kAMdAPreDecL, reg(p) + 8);
|
|
p->MainClass = kIKindMOVEMRmML;
|
|
} else {
|
|
if (CheckControlAltAddrMode(p)) {
|
|
p->MainClass = kIKindMOVEMrmL;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
case 5:
|
|
if (b76(p) == 3) {
|
|
if ((mode(p) == 7) && (reg(p) == 4)) {
|
|
/* the ILLEGAL instruction */
|
|
p->MainClass = kIKindIllegal;
|
|
} else {
|
|
/* Tas 0100101011mmmrrr */
|
|
p->opsize = 1;
|
|
if (CheckDataAltAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
if (0 != mode(p)) {
|
|
p->Cycles = (14 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc + WrAvgXtraCyc);
|
|
} else {
|
|
p->Cycles = (4 * kCycleScale
|
|
+ RdAvgXtraCyc);
|
|
}
|
|
p->Cycles +=
|
|
OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindTas;
|
|
}
|
|
}
|
|
} else {
|
|
/* Tst 01001010ssmmmrrr */
|
|
FindOpSizeFromb76(p);
|
|
if (b76(p) == 0) {
|
|
if (CheckDataAltAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
p->Cycles =
|
|
(4 * kCycleScale + RdAvgXtraCyc);
|
|
p->Cycles +=
|
|
OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindTst;
|
|
}
|
|
} else {
|
|
if (IsValidAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
p->Cycles =
|
|
(4 * kCycleScale + RdAvgXtraCyc);
|
|
p->Cycles +=
|
|
OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindTst;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case 6:
|
|
if (((p->opcode >> 7) & 1) == 1) {
|
|
/* MOVEM mem to reg 0100110011smmmrrr */
|
|
p->opsize = 2 * b76(p) - 2;
|
|
if (mode(p) == 3) {
|
|
#if WantCycByPriOp
|
|
p->Cycles = 4 * kCycleScale + RdAvgXtraCyc;
|
|
p->Cycles += MoveMEACalcCyc(p, mode(p), reg(p));
|
|
if (4 == p->opsize) {
|
|
p->Cycles += MoveAvgN * 8 * kCycleScale
|
|
+ 2 * MoveAvgN * RdAvgXtraCyc;
|
|
} else {
|
|
p->Cycles += MoveAvgN * 4 * kCycleScale
|
|
+ MoveAvgN * RdAvgXtraCyc;
|
|
}
|
|
#endif
|
|
SetDcoArgFields(p, falseblnr,
|
|
kAMdAPosIncL, reg(p) + 8);
|
|
if (b76(p) == 2) {
|
|
p->MainClass = kIKindMOVEMApRW;
|
|
} else {
|
|
p->MainClass = kIKindMOVEMApRL;
|
|
}
|
|
} else {
|
|
if (CheckControlAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
p->Cycles = 4 * kCycleScale + RdAvgXtraCyc;
|
|
p->Cycles += MoveMEACalcCyc(p,
|
|
mode(p), reg(p));
|
|
if (4 == p->opsize) {
|
|
p->Cycles += MoveAvgN * 8 * kCycleScale
|
|
+ 2 * MoveAvgN * RdAvgXtraCyc;
|
|
} else {
|
|
p->Cycles += MoveAvgN * 4 * kCycleScale
|
|
+ MoveAvgN * RdAvgXtraCyc;
|
|
}
|
|
#endif
|
|
if (4 == p->opsize) {
|
|
p->MainClass = kIKindMOVEMmrL;
|
|
} else {
|
|
p->MainClass = kIKindMOVEMmrW;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
#if Use68020
|
|
p->opsize = 4;
|
|
|
|
if (CheckDataAddrMode(p)) {
|
|
if (((p->opcode >> 6) & 1) == 1) {
|
|
/* DIVU 0100110001mmmrrr 0rrr0s0000000rrr */
|
|
/* DIVS 0100110001mmmrrr 0rrr1s0000000rrr */
|
|
p->MainClass = kIKindDivL;
|
|
} else {
|
|
/* MULU 0100110000mmmrrr 0rrr0s0000000rrr */
|
|
/* MULS 0100110000mmmrrr 0rrr1s0000000rrr */
|
|
p->MainClass = kIKindMulL;
|
|
}
|
|
}
|
|
#else
|
|
p->MainClass = kIKindIllegal;
|
|
#endif
|
|
}
|
|
break;
|
|
case 7:
|
|
default: /* keep compiler happy */
|
|
switch (b76(p)) {
|
|
case 0:
|
|
p->MainClass = kIKindIllegal;
|
|
break;
|
|
case 1:
|
|
switch (mode(p)) {
|
|
case 0:
|
|
case 1:
|
|
/* Trap 010011100100vvvv */
|
|
#if WantCycByPriOp
|
|
p->Cycles = (34 * kCycleScale
|
|
+ 4 * RdAvgXtraCyc
|
|
+ 3 * WrAvgXtraCyc);
|
|
#endif
|
|
SetDcoArgFields(p, falseblnr,
|
|
kAMdDat4, (p->opcode & 15) + 32);
|
|
p->MainClass = kIKindTrap;
|
|
break;
|
|
case 2:
|
|
/* Link */
|
|
#if WantCycByPriOp
|
|
p->Cycles = (16 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc
|
|
+ 2 * WrAvgXtraCyc);
|
|
#endif
|
|
SetDcoArgFields(p, falseblnr,
|
|
kAMdRegL, reg(p) + 8);
|
|
if (reg(p) == 6) {
|
|
p->MainClass = kIKindLinkA6;
|
|
} else {
|
|
p->MainClass = kIKindLink;
|
|
}
|
|
break;
|
|
case 3:
|
|
/* Unlk */
|
|
#if WantCycByPriOp
|
|
p->Cycles = (12 * kCycleScale
|
|
+ 3 * RdAvgXtraCyc);
|
|
#endif
|
|
SetDcoArgFields(p, falseblnr,
|
|
kAMdRegL, reg(p) + 8);
|
|
if (reg(p) == 6) {
|
|
p->MainClass = kIKindUnlkA6;
|
|
} else {
|
|
p->MainClass = kIKindUnlk;
|
|
}
|
|
break;
|
|
case 4:
|
|
/* MOVE USP 0100111001100aaa */
|
|
#if WantCycByPriOp
|
|
p->Cycles =
|
|
(4 * kCycleScale + RdAvgXtraCyc);
|
|
#endif
|
|
SetDcoArgFields(p, falseblnr,
|
|
kAMdRegL, reg(p) + 8);
|
|
p->MainClass = kIKindMoveRUSP;
|
|
break;
|
|
case 5:
|
|
/* MOVE USP 0100111001101aaa */
|
|
#if WantCycByPriOp
|
|
p->Cycles =
|
|
(4 * kCycleScale + RdAvgXtraCyc);
|
|
#endif
|
|
SetDcoArgFields(p, falseblnr,
|
|
kAMdRegL, reg(p) + 8);
|
|
p->MainClass = kIKindMoveUSPR;
|
|
break;
|
|
case 6:
|
|
switch (reg(p)) {
|
|
case 0:
|
|
/* Reset 0100111001100000 */
|
|
#if WantCycByPriOp
|
|
p->Cycles = (132 * kCycleScale
|
|
+ RdAvgXtraCyc);
|
|
#endif
|
|
p->MainClass = kIKindReset;
|
|
break;
|
|
case 1:
|
|
/* Nop = 0100111001110001 */
|
|
#if WantCycByPriOp
|
|
p->Cycles = (4 * kCycleScale
|
|
+ RdAvgXtraCyc);
|
|
#endif
|
|
p->MainClass = kIKindNop;
|
|
break;
|
|
case 2:
|
|
/* Stop 0100111001110010 */
|
|
#if WantCycByPriOp
|
|
p->Cycles = (4 * kCycleScale);
|
|
#endif
|
|
p->MainClass = kIKindStop;
|
|
break;
|
|
case 3:
|
|
/* Rte 0100111001110011 */
|
|
#if WantCycByPriOp
|
|
p->Cycles = (20 * kCycleScale
|
|
+ 5 * RdAvgXtraCyc);
|
|
#endif
|
|
p->MainClass = kIKindRte;
|
|
break;
|
|
case 4:
|
|
/* Rtd 0100111001110100 */
|
|
#if Use68020
|
|
p->MainClass = kIKindRtd;
|
|
#else
|
|
p->MainClass = kIKindIllegal;
|
|
#endif
|
|
break;
|
|
case 5:
|
|
/* Rts 0100111001110101 */
|
|
#if WantCycByPriOp
|
|
p->Cycles = (16 * kCycleScale
|
|
+ 4 * RdAvgXtraCyc);
|
|
#endif
|
|
p->MainClass = kIKindRts;
|
|
break;
|
|
case 6:
|
|
/* TrapV 0100111001110110 */
|
|
#if WantCycByPriOp
|
|
p->Cycles = (4 * kCycleScale
|
|
+ RdAvgXtraCyc);
|
|
#endif
|
|
p->MainClass = kIKindTrapV;
|
|
break;
|
|
case 7:
|
|
default: /* keep compiler happy */
|
|
/* Rtr 0100111001110111 */
|
|
#if WantCycByPriOp
|
|
p->Cycles = (20 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc);
|
|
#endif
|
|
p->MainClass = kIKindRtr;
|
|
break;
|
|
}
|
|
break;
|
|
case 7:
|
|
default: /* keep compiler happy */
|
|
#if Use68020
|
|
/* MOVEC 010011100111101m */
|
|
switch (reg(p)) {
|
|
case 2:
|
|
p->MainClass = kIKindMoveCEa;
|
|
break;
|
|
case 3:
|
|
p->MainClass = kIKindMoveEaC;
|
|
break;
|
|
default:
|
|
p->MainClass = kIKindIllegal;
|
|
break;
|
|
}
|
|
#else
|
|
p->MainClass = kIKindIllegal;
|
|
#endif
|
|
break;
|
|
}
|
|
break;
|
|
case 2:
|
|
/* Jsr 0100111010mmmrrr */
|
|
if (CheckControlAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
switch (mode(p)) {
|
|
case 2:
|
|
p->Cycles = (16 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc
|
|
+ 2 * WrAvgXtraCyc);
|
|
break;
|
|
case 5:
|
|
p->Cycles = (18 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc
|
|
+ 2 * WrAvgXtraCyc);
|
|
break;
|
|
case 6:
|
|
p->Cycles = (22 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc
|
|
+ 2 * WrAvgXtraCyc);
|
|
break;
|
|
case 7:
|
|
default: /* keep compiler happy */
|
|
switch (reg(p)) {
|
|
case 0:
|
|
p->Cycles =
|
|
(18 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc
|
|
+ 2 * WrAvgXtraCyc);
|
|
break;
|
|
case 1:
|
|
p->Cycles =
|
|
(20 * kCycleScale
|
|
+ 3 * RdAvgXtraCyc
|
|
+ 2 * WrAvgXtraCyc);
|
|
break;
|
|
case 2:
|
|
p->Cycles =
|
|
(18 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc
|
|
+ 2 * WrAvgXtraCyc);
|
|
break;
|
|
case 3:
|
|
default:
|
|
/* keep compiler happy */
|
|
p->Cycles =
|
|
(22 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc
|
|
+ 2 * WrAvgXtraCyc);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
#endif
|
|
p->MainClass = kIKindJsr;
|
|
}
|
|
break;
|
|
case 3:
|
|
default: /* keep compiler happy */
|
|
/* JMP 0100111011mmmrrr */
|
|
if (CheckControlAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
switch (mode(p)) {
|
|
case 2:
|
|
p->Cycles = (8 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc);
|
|
break;
|
|
case 5:
|
|
p->Cycles = (10 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc);
|
|
break;
|
|
case 6:
|
|
p->Cycles = (14 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc);
|
|
break;
|
|
case 7:
|
|
default: /* keep compiler happy */
|
|
switch (reg(p)) {
|
|
case 0:
|
|
p->Cycles =
|
|
(10 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc);
|
|
break;
|
|
case 1:
|
|
p->Cycles =
|
|
(12 * kCycleScale
|
|
+ 3 * RdAvgXtraCyc);
|
|
break;
|
|
case 2:
|
|
p->Cycles =
|
|
(10 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc);
|
|
break;
|
|
case 3:
|
|
default:
|
|
/* keep compiler happy */
|
|
p->Cycles =
|
|
(14 * kCycleScale
|
|
+ 3 * RdAvgXtraCyc);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
#endif
|
|
p->MainClass = kIKindJmp;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
LOCALPROCUSEDONCE DeCode5(WorkR *p)
|
|
{
|
|
if (b76(p) == 3) {
|
|
p->DecOp.y.v[0].ArgDat = (p->opcode >> 8) & 15;
|
|
if (mode(p) == 1) {
|
|
/* DBcc 0101cccc11001ddd */
|
|
#if WantCycByPriOp
|
|
#if WantCloserCyc
|
|
p->Cycles = 0;
|
|
#else
|
|
p->Cycles = (11 * kCycleScale + 2 * RdAvgXtraCyc);
|
|
/*
|
|
average of cc true 12(2/0),
|
|
cc false taken 10(2/0),
|
|
and not 14(3/0)
|
|
*/
|
|
#endif
|
|
#endif
|
|
SetDcoArgFields(p, falseblnr, kAMdRegW, reg(p));
|
|
if (1 == ((p->opcode >> 8) & 15)) {
|
|
p->MainClass = kIKindDBF;
|
|
} else {
|
|
p->MainClass = kIKindDBcc;
|
|
}
|
|
} else {
|
|
#if Use68020
|
|
if ((mode(p) == 7) && (reg(p) >= 2)) {
|
|
/* TRAPcc 0101cccc11111sss */
|
|
p->DecOp.y.v[0].ArgDat = reg(p);
|
|
p->MainClass = kIKindTRAPcc;
|
|
} else
|
|
#endif
|
|
{
|
|
p->opsize = 1;
|
|
/* Scc 0101cccc11mmmrrr */
|
|
if (CheckDataAltAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
if (0 != mode(p)) {
|
|
p->Cycles = (8 * kCycleScale
|
|
+ RdAvgXtraCyc + WrAvgXtraCyc);
|
|
} else {
|
|
#if WantCloserCyc
|
|
p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
|
|
#else
|
|
p->Cycles = (5 * kCycleScale + RdAvgXtraCyc);
|
|
/* 4 when false, 6 when true */
|
|
#endif
|
|
}
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindScc;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (mode(p) == 1) {
|
|
p->opsize = b8(p) * 2 + 2;
|
|
SetDcoArgFields(p, trueblnr, kAMdDat4,
|
|
octdat(rg9(p)));
|
|
SetDcoArgFields(p, falseblnr, kAMdRegL,
|
|
reg(p) + 8);
|
|
/* always long, regardless of opsize */
|
|
if (b8(p) == 0) {
|
|
#if WantCycByPriOp
|
|
p->Cycles = (4 == p->opsize)
|
|
? (8 * kCycleScale + RdAvgXtraCyc)
|
|
: (4 * kCycleScale + RdAvgXtraCyc);
|
|
#endif
|
|
p->MainClass = kIKindAddQA; /* AddQA 0101nnn0ss001rrr */
|
|
} else {
|
|
#if WantCycByPriOp
|
|
p->Cycles = (8 * kCycleScale + RdAvgXtraCyc);
|
|
#endif
|
|
p->MainClass = kIKindSubQA; /* SubQA 0101nnn1ss001rrr */
|
|
}
|
|
} else {
|
|
FindOpSizeFromb76(p);
|
|
SetDcoArgFields(p, trueblnr, kAMdDat4,
|
|
octdat(rg9(p)));
|
|
if (CheckValidAddrMode(p,
|
|
mode(p), reg(p), kAddrValidDataAlt, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
if (0 != mode(p)) {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (12 * kCycleScale
|
|
+ RdAvgXtraCyc + 2 * WrAvgXtraCyc)
|
|
: (8 * kCycleScale
|
|
+ RdAvgXtraCyc + WrAvgXtraCyc);
|
|
} else {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (8 * kCycleScale + RdAvgXtraCyc)
|
|
: (4 * kCycleScale + RdAvgXtraCyc);
|
|
}
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
if (b8(p) == 0) {
|
|
/* AddQ 0101nnn0ssmmmrrr */
|
|
#if 0
|
|
if (CheckDataAltAddrMode(p)) {
|
|
p->MainClass = kIKindAddQ;
|
|
}
|
|
#endif
|
|
p->MainClass = kIKindAddB + OpSizeOffset(p);
|
|
} else {
|
|
/* SubQ 0101nnn1ssmmmrrr */
|
|
#if 0
|
|
if (CheckDataAltAddrMode(p)) {
|
|
p->MainClass = kIKindSubQ;
|
|
}
|
|
#endif
|
|
p->MainClass = kIKindSubB + OpSizeOffset(p);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
LOCALPROCUSEDONCE DeCode6(WorkR *p)
|
|
{
|
|
ui5b cond = (p->opcode >> 8) & 15;
|
|
|
|
if (cond == 1) {
|
|
/* Bsr 01100001nnnnnnnn */
|
|
#if WantCycByPriOp
|
|
p->Cycles = (18 * kCycleScale
|
|
+ 2 * RdAvgXtraCyc + 2 * WrAvgXtraCyc);
|
|
#endif
|
|
if (0 == (p->opcode & 255)) {
|
|
p->MainClass = kIKindBsrW;
|
|
} else
|
|
#if Use68020
|
|
if (255 == (p->opcode & 255)) {
|
|
p->MainClass = kIKindBsrL;
|
|
} else
|
|
#endif
|
|
{
|
|
p->MainClass = kIKindBsrB;
|
|
p->DecOp.y.v[1].ArgDat = p->opcode & 255;
|
|
}
|
|
} else if (cond == 0) {
|
|
/* Bra 01100000nnnnnnnn */
|
|
#if WantCycByPriOp
|
|
p->Cycles = (10 * kCycleScale + 2 * RdAvgXtraCyc);
|
|
#endif
|
|
if (0 == (p->opcode & 255)) {
|
|
p->MainClass = kIKindBraW;
|
|
} else
|
|
#if Use68020
|
|
if (255 == (p->opcode & 255)) {
|
|
p->MainClass = kIKindBraL;
|
|
} else
|
|
#endif
|
|
{
|
|
p->MainClass = kIKindBraB;
|
|
p->DecOp.y.v[1].ArgDat = p->opcode & 255;
|
|
}
|
|
} else {
|
|
p->DecOp.y.v[0].ArgDat = cond;
|
|
/* Bcc 0110ccccnnnnnnnn */
|
|
if (0 == (p->opcode & 255)) {
|
|
#if WantCycByPriOp
|
|
#if WantCloserCyc
|
|
p->Cycles = 0;
|
|
#else
|
|
p->Cycles = (11 * kCycleScale + 2 * RdAvgXtraCyc);
|
|
/* average of branch taken 10(2/0) and not 12(2/0) */
|
|
#endif
|
|
#endif
|
|
p->MainClass = kIKindBccW;
|
|
} else
|
|
#if Use68020
|
|
if (255 == (p->opcode & 255)) {
|
|
p->MainClass = kIKindBccL;
|
|
} else
|
|
#endif
|
|
{
|
|
#if WantCycByPriOp
|
|
#if WantCloserCyc
|
|
p->Cycles = 0;
|
|
#else
|
|
p->Cycles = (9 * kCycleScale
|
|
+ RdAvgXtraCyc + (RdAvgXtraCyc / 2));
|
|
/* average of branch taken 10(2/0) and not 8(1/0) */
|
|
#endif
|
|
#endif
|
|
p->MainClass = kIKindBccB;
|
|
p->DecOp.y.v[1].ArgDat = p->opcode & 255;
|
|
}
|
|
}
|
|
}
|
|
|
|
LOCALPROCUSEDONCE DeCode7(WorkR *p)
|
|
{
|
|
if (b8(p) == 0) {
|
|
p->opsize = 4;
|
|
#if WantCycByPriOp
|
|
p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
|
|
#endif
|
|
p->MainClass = kIKindMoveQ;
|
|
p->DecOp.y.v[0].ArgDat = p->opcode & 255;
|
|
p->DecOp.y.v[1].ArgDat = rg9(p);
|
|
} else {
|
|
p->MainClass = kIKindIllegal;
|
|
}
|
|
}
|
|
|
|
LOCALPROCUSEDONCE DeCode8(WorkR *p)
|
|
{
|
|
if (b76(p) == 3) {
|
|
p->opsize = 2;
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidData, trueblnr))
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
if (b8(p) == 0) {
|
|
/* DivU 1000ddd011mmmrrr */
|
|
#if WantCycByPriOp
|
|
p->Cycles = RdAvgXtraCyc;
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#if ! WantCloserCyc
|
|
p->Cycles += 133 * kCycleScale;
|
|
/*
|
|
worse case 140, less than ten percent
|
|
different from best case
|
|
*/
|
|
#endif
|
|
#endif
|
|
p->MainClass = kIKindDivU;
|
|
} else {
|
|
/* DivS 1000ddd111mmmrrr */
|
|
#if WantCycByPriOp
|
|
p->Cycles = RdAvgXtraCyc;
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#if ! WantCloserCyc
|
|
p->Cycles += 150 * kCycleScale;
|
|
/*
|
|
worse case 158, less than ten percent different
|
|
from best case
|
|
*/
|
|
#endif
|
|
#endif
|
|
p->MainClass = kIKindDivS;
|
|
}
|
|
}
|
|
} else {
|
|
if (b8(p) == 0) {
|
|
/* OR 1000ddd0ssmmmrrr */
|
|
#if 0
|
|
if (CheckDataAddrMode(p)) {
|
|
p->MainClass = kIKindOrEaD;
|
|
}
|
|
#endif
|
|
FindOpSizeFromb76(p);
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidData, trueblnr))
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
if (4 == p->opsize) {
|
|
if ((mode(p) < 2)
|
|
|| ((7 == mode(p)) && (reg(p) == 4)))
|
|
{
|
|
p->Cycles = (8 * kCycleScale + RdAvgXtraCyc);
|
|
} else {
|
|
p->Cycles = (6 * kCycleScale + RdAvgXtraCyc);
|
|
}
|
|
} else {
|
|
p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
|
|
}
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindOrEaD;
|
|
}
|
|
} else {
|
|
if (mode(p) < 2) {
|
|
switch (b76(p)) {
|
|
case 0:
|
|
/* SBCD 1000xxx10000mxxx */
|
|
#if WantCycByPriOp
|
|
if (0 != mode(p)) {
|
|
p->Cycles = (18 * kCycleScale
|
|
+ 3 * RdAvgXtraCyc + WrAvgXtraCyc);
|
|
} else {
|
|
p->Cycles = (6 * kCycleScale
|
|
+ RdAvgXtraCyc);
|
|
}
|
|
#endif
|
|
p->opsize = 1;
|
|
if (mode(p) == 0) {
|
|
if (CheckValidAddrMode(p, 0, reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
p->MainClass = kIKindSbcd;
|
|
}
|
|
} else {
|
|
if (CheckValidAddrMode(p, 4, reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, 4, rg9(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
p->MainClass = kIKindSbcd;
|
|
}
|
|
}
|
|
break;
|
|
#if Use68020
|
|
case 1:
|
|
/* PACK 1000rrr10100mrrr */
|
|
if (mode(p) == 0) {
|
|
p->opsize = 2;
|
|
if (CheckValidAddrMode(p, 0, reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
{
|
|
p->opsize = 1;
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
p->MainClass = kIKindPack;
|
|
}
|
|
}
|
|
} else {
|
|
p->opsize = 2;
|
|
if (CheckValidAddrMode(p, 4, reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
{
|
|
p->opsize = 1;
|
|
if (CheckValidAddrMode(p, 4, rg9(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
p->MainClass = kIKindPack;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case 2:
|
|
/* UNPK 1000rrr11000mrrr */
|
|
if (mode(p) == 0) {
|
|
p->opsize = 1;
|
|
if (CheckValidAddrMode(p, 0, reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
{
|
|
p->opsize = 2;
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
p->MainClass = kIKindUnpk;
|
|
}
|
|
}
|
|
} else {
|
|
p->opsize = 1;
|
|
if (CheckValidAddrMode(p, 4, reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
{
|
|
p->opsize = 2;
|
|
if (CheckValidAddrMode(p, 4, rg9(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
p->MainClass = kIKindUnpk;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
#endif
|
|
default:
|
|
p->MainClass = kIKindIllegal;
|
|
break;
|
|
}
|
|
} else {
|
|
/* OR 1000ddd1ssmmmrrr */
|
|
#if 0
|
|
if (CheckDataAltAddrMode(p)) {
|
|
p->MainClass = kIKindOrDEa;
|
|
}
|
|
#endif
|
|
FindOpSizeFromb76(p);
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidAltMem, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
p->Cycles = (4 == p->opsize)
|
|
? (12 * kCycleScale
|
|
+ RdAvgXtraCyc + 2 * WrAvgXtraCyc)
|
|
: (8 * kCycleScale
|
|
+ RdAvgXtraCyc + WrAvgXtraCyc);
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindOrDEa;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
LOCALPROCUSEDONCE DeCode9(WorkR *p)
|
|
{
|
|
if (b76(p) == 3) {
|
|
/* SUBA 1001dddm11mmmrrr */
|
|
#if 0
|
|
if (IsValidAddrMode(p)) {
|
|
p->MainClass = kIKindSubA;
|
|
}
|
|
#endif
|
|
p->opsize = b8(p) * 2 + 2;
|
|
SetDcoArgFields(p, falseblnr, kAMdRegL, rg9(p) + 8);
|
|
/* always long, regardless of opsize */
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
if (4 == p->opsize) {
|
|
if ((mode(p) < 2) || ((7 == mode(p)) && (reg(p) == 4)))
|
|
{
|
|
p->Cycles = (8 * kCycleScale + RdAvgXtraCyc);
|
|
} else {
|
|
p->Cycles = (6 * kCycleScale + RdAvgXtraCyc);
|
|
}
|
|
} else {
|
|
p->Cycles = (8 * kCycleScale + RdAvgXtraCyc);
|
|
}
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindSubA;
|
|
}
|
|
} else {
|
|
if (b8(p) == 0) {
|
|
/* SUB 1001ddd0ssmmmrrr */
|
|
#if 0
|
|
if (IsValidAddrMode(p)) {
|
|
p->MainClass = kIKindSubEaR;
|
|
}
|
|
#endif
|
|
FindOpSizeFromb76(p);
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
if (4 == p->opsize) {
|
|
if ((mode(p) < 2)
|
|
|| ((7 == mode(p)) && (reg(p) == 4)))
|
|
{
|
|
p->Cycles = (8 * kCycleScale + RdAvgXtraCyc);
|
|
} else {
|
|
p->Cycles = (6 * kCycleScale + RdAvgXtraCyc);
|
|
}
|
|
} else {
|
|
p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
|
|
}
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindSubB + OpSizeOffset(p);
|
|
}
|
|
} else {
|
|
if (mode(p) == 0) {
|
|
/* SUBX 1001ddd1ss000rrr */
|
|
/* p->MainClass = kIKindSubXd; */
|
|
FindOpSizeFromb76(p);
|
|
if (CheckValidAddrMode(p, 0, reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
p->Cycles = (4 == p->opsize)
|
|
? (8 * kCycleScale + RdAvgXtraCyc)
|
|
: (4 * kCycleScale + RdAvgXtraCyc);
|
|
#endif
|
|
p->MainClass = kIKindSubXB + OpSizeOffset(p);
|
|
}
|
|
} else if (mode(p) == 1) {
|
|
/* SUBX 1001ddd1ss001rrr */
|
|
/* p->MainClass = kIKindSubXm; */
|
|
FindOpSizeFromb76(p);
|
|
if (CheckValidAddrMode(p, 4, reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, 4, rg9(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
p->Cycles = (4 == p->opsize)
|
|
? (30 * kCycleScale
|
|
+ 5 * RdAvgXtraCyc + 2 * WrAvgXtraCyc)
|
|
: (18 * kCycleScale
|
|
+ 3 * RdAvgXtraCyc + 1 * WrAvgXtraCyc);
|
|
#endif
|
|
p->MainClass = kIKindSubXB + OpSizeOffset(p);
|
|
}
|
|
} else {
|
|
/* SUB 1001ddd1ssmmmrrr */
|
|
#if 0
|
|
if (CheckAltMemAddrMode(p)) {
|
|
p->MainClass = kIKindSubREa;
|
|
}
|
|
#endif
|
|
FindOpSizeFromb76(p);
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, mode(p),
|
|
reg(p), kAddrValidAltMem, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
p->Cycles = (4 == p->opsize)
|
|
? (12 * kCycleScale
|
|
+ RdAvgXtraCyc + 2 * WrAvgXtraCyc)
|
|
: (8 * kCycleScale
|
|
+ RdAvgXtraCyc + WrAvgXtraCyc);
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindSubB + OpSizeOffset(p);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
LOCALPROCUSEDONCE DeCodeA(WorkR *p)
|
|
{
|
|
#if WantCycByPriOp
|
|
p->Cycles = (34 * kCycleScale
|
|
+ 4 * RdAvgXtraCyc + 3 * WrAvgXtraCyc);
|
|
#endif
|
|
p->MainClass = kIKindA;
|
|
}
|
|
|
|
LOCALPROCUSEDONCE DeCodeB(WorkR *p)
|
|
{
|
|
if (b76(p) == 3) {
|
|
/* CMPA 1011ddds11mmmrrr */
|
|
#if 0
|
|
if (IsValidAddrMode(p)) {
|
|
p->MainClass = kIKindCmpA;
|
|
}
|
|
#endif
|
|
p->opsize = b8(p) * 2 + 2;
|
|
SetDcoArgFields(p, falseblnr, kAMdRegL, rg9(p) + 8);
|
|
/* always long, regardless of opsize */
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
p->Cycles = (6 * kCycleScale + RdAvgXtraCyc);
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindCmpA;
|
|
}
|
|
} else if (b8(p) == 1) {
|
|
if (mode(p) == 1) {
|
|
/* CmpM 1011ddd1ss001rrr */
|
|
#if 0
|
|
p->MainClass = kIKindCmpM;
|
|
#endif
|
|
FindOpSizeFromb76(p);
|
|
if (CheckValidAddrMode(p, 3, reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, 3, rg9(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
p->Cycles = (4 == p->opsize)
|
|
? (20 * kCycleScale + 5 * RdAvgXtraCyc)
|
|
: (12 * kCycleScale + 3 * RdAvgXtraCyc);
|
|
#endif
|
|
p->MainClass = kIKindCmpB + OpSizeOffset(p);
|
|
}
|
|
} else {
|
|
#if 0
|
|
/* Eor 1011ddd1ssmmmrrr */
|
|
if (CheckDataAltAddrMode(p)) {
|
|
p->MainClass = kIKindEor;
|
|
}
|
|
#endif
|
|
FindOpSizeFromb76(p);
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidDataAlt, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
if (0 != mode(p)) {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (12 * kCycleScale
|
|
+ RdAvgXtraCyc + 2 * WrAvgXtraCyc)
|
|
: (8 * kCycleScale
|
|
+ RdAvgXtraCyc + WrAvgXtraCyc);
|
|
} else {
|
|
p->Cycles = (4 == p->opsize)
|
|
? (8 * kCycleScale + RdAvgXtraCyc)
|
|
: (4 * kCycleScale + RdAvgXtraCyc);
|
|
}
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindEor;
|
|
}
|
|
}
|
|
} else {
|
|
/* Cmp 1011ddd0ssmmmrrr */
|
|
#if 0
|
|
if (IsValidAddrMode(p)) {
|
|
p->MainClass = kIKindCmp;
|
|
}
|
|
#endif
|
|
FindOpSizeFromb76(p);
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
p->Cycles = (4 == p->opsize)
|
|
? (6 * kCycleScale + RdAvgXtraCyc)
|
|
: (4 * kCycleScale + RdAvgXtraCyc);
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindCmpB + OpSizeOffset(p);
|
|
}
|
|
}
|
|
}
|
|
|
|
LOCALPROCUSEDONCE DeCodeC(WorkR *p)
|
|
{
|
|
if (b76(p) == 3) {
|
|
p->opsize = 2;
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidData, trueblnr))
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
#if WantCloserCyc
|
|
p->Cycles = (38 * kCycleScale + RdAvgXtraCyc);
|
|
#else
|
|
p->Cycles = (54 * kCycleScale + RdAvgXtraCyc);
|
|
/* worst case 70, best case 38 */
|
|
#endif
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
if (b8(p) == 0) {
|
|
/* MulU 1100ddd011mmmrrr */
|
|
p->MainClass = kIKindMulU;
|
|
} else {
|
|
/* MulS 1100ddd111mmmrrr */
|
|
p->MainClass = kIKindMulS;
|
|
}
|
|
}
|
|
} else {
|
|
if (b8(p) == 0) {
|
|
/* And 1100ddd0ssmmmrrr */
|
|
#if 0
|
|
if (CheckDataAddrMode(p)) {
|
|
p->MainClass = kIKindAndEaD;
|
|
}
|
|
#endif
|
|
FindOpSizeFromb76(p);
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidData, trueblnr))
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
if (4 == p->opsize) {
|
|
if ((mode(p) < 2)
|
|
|| ((7 == mode(p)) && (reg(p) == 4)))
|
|
{
|
|
p->Cycles = (8 * kCycleScale + RdAvgXtraCyc);
|
|
} else {
|
|
p->Cycles = (6 * kCycleScale + RdAvgXtraCyc);
|
|
}
|
|
} else {
|
|
p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
|
|
}
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindAndEaD;
|
|
}
|
|
} else {
|
|
if (mode(p) < 2) {
|
|
switch (b76(p)) {
|
|
case 0:
|
|
/* ABCD 1100ddd10000mrrr */
|
|
#if WantCycByPriOp
|
|
if (0 != mode(p)) {
|
|
p->Cycles = (18 * kCycleScale
|
|
+ 3 * RdAvgXtraCyc + WrAvgXtraCyc);
|
|
} else {
|
|
p->Cycles = (6 * kCycleScale
|
|
+ RdAvgXtraCyc);
|
|
}
|
|
#endif
|
|
p->opsize = 1;
|
|
if (mode(p) == 0) {
|
|
if (CheckValidAddrMode(p, 0, reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
p->MainClass = kIKindAbcd;
|
|
}
|
|
} else {
|
|
if (CheckValidAddrMode(p, 4, reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, 4, rg9(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
p->MainClass = kIKindAbcd;
|
|
}
|
|
}
|
|
break;
|
|
case 1:
|
|
/* Exg 1100ddd10100trrr */
|
|
#if WantCycByPriOp
|
|
p->Cycles = (6 * kCycleScale + RdAvgXtraCyc);
|
|
#endif
|
|
p->opsize = 4;
|
|
if (mode(p) == 0) {
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, 0, reg(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
p->MainClass = kIKindExg;
|
|
}
|
|
} else {
|
|
if (CheckValidAddrMode(p, 1, rg9(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, 1, reg(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
p->MainClass = kIKindExg;
|
|
}
|
|
}
|
|
break;
|
|
case 2:
|
|
default: /* keep compiler happy */
|
|
if (mode(p) == 0) {
|
|
p->MainClass = kIKindIllegal;
|
|
} else {
|
|
/* Exg 1100ddd110001rrr */
|
|
#if WantCycByPriOp
|
|
p->Cycles = (6 * kCycleScale
|
|
+ RdAvgXtraCyc);
|
|
#endif
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, 1, reg(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
p->MainClass = kIKindExg;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
} else {
|
|
/* And 1100ddd1ssmmmrrr */
|
|
#if 0
|
|
if (CheckAltMemAddrMode(p)) {
|
|
p->MainClass = kIKindAndDEa;
|
|
}
|
|
#endif
|
|
FindOpSizeFromb76(p);
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidAltMem, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
p->Cycles = (4 == p->opsize)
|
|
? (12 * kCycleScale
|
|
+ RdAvgXtraCyc + 2 * WrAvgXtraCyc)
|
|
: (8 * kCycleScale
|
|
+ RdAvgXtraCyc + WrAvgXtraCyc);
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindAndDEa;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
LOCALPROCUSEDONCE DeCodeD(WorkR *p)
|
|
{
|
|
if (b76(p) == 3) {
|
|
/* ADDA 1101dddm11mmmrrr */
|
|
p->opsize = b8(p) * 2 + 2;
|
|
SetDcoArgFields(p, falseblnr, kAMdRegL, rg9(p) + 8);
|
|
/* always long, regardless of opsize */
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
if (4 == p->opsize) {
|
|
if ((mode(p) < 2) || ((7 == mode(p)) && (reg(p) == 4)))
|
|
{
|
|
p->Cycles = (8 * kCycleScale + RdAvgXtraCyc);
|
|
} else {
|
|
p->Cycles = (6 * kCycleScale + RdAvgXtraCyc);
|
|
}
|
|
} else {
|
|
p->Cycles = (8 * kCycleScale + RdAvgXtraCyc);
|
|
}
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindAddA;
|
|
}
|
|
} else {
|
|
if (b8(p) == 0) {
|
|
/* ADD 1101ddd0ssmmmrrr */
|
|
FindOpSizeFromb76(p);
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
if (4 == p->opsize) {
|
|
if ((mode(p) < 2)
|
|
|| ((7 == mode(p)) && (reg(p) == 4)))
|
|
{
|
|
p->Cycles = (8 * kCycleScale + RdAvgXtraCyc);
|
|
} else {
|
|
p->Cycles = (6 * kCycleScale + RdAvgXtraCyc);
|
|
}
|
|
} else {
|
|
p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
|
|
}
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindAddB + OpSizeOffset(p);
|
|
}
|
|
} else {
|
|
if (mode(p) == 0) {
|
|
/* ADDX 1101ddd1ss000rrr */
|
|
/* p->MainClass = kIKindAddXd; */
|
|
FindOpSizeFromb76(p);
|
|
if (CheckValidAddrMode(p, 0, reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
p->Cycles = (4 == p->opsize)
|
|
? (8 * kCycleScale + RdAvgXtraCyc)
|
|
: (4 * kCycleScale + RdAvgXtraCyc);
|
|
#endif
|
|
p->MainClass = kIKindAddXB + OpSizeOffset(p);
|
|
}
|
|
} else if (mode(p) == 1) {
|
|
/* p->MainClass = kIKindAddXm; */
|
|
FindOpSizeFromb76(p);
|
|
if (CheckValidAddrMode(p, 4, reg(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, 4, rg9(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
p->Cycles = (4 == p->opsize)
|
|
? (30 * kCycleScale
|
|
+ 5 * RdAvgXtraCyc + 2 * WrAvgXtraCyc)
|
|
: (18 * kCycleScale
|
|
+ 3 * RdAvgXtraCyc + 1 * WrAvgXtraCyc);
|
|
#endif
|
|
p->MainClass = kIKindAddXB + OpSizeOffset(p);
|
|
}
|
|
} else {
|
|
/* ADD 1101ddd1ssmmmrrr */
|
|
FindOpSizeFromb76(p);
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, mode(p), reg(p),
|
|
kAddrValidAltMem, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
p->Cycles = (4 == p->opsize)
|
|
? (12 * kCycleScale
|
|
+ RdAvgXtraCyc + 2 * WrAvgXtraCyc)
|
|
: (8 * kCycleScale
|
|
+ RdAvgXtraCyc + WrAvgXtraCyc);
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = kIKindAddB + OpSizeOffset(p);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
LOCALFUNC ui5r rolops(WorkR *p, ui5r x)
|
|
{
|
|
ui5r binop;
|
|
|
|
binop = (x << 1);
|
|
if (! b8(p)) {
|
|
binop++; /* 'R' */
|
|
} /* else 'L' */
|
|
|
|
return kIKindAslB + 3 * binop + OpSizeOffset(p);
|
|
}
|
|
|
|
LOCALPROCUSEDONCE DeCodeE(WorkR *p)
|
|
{
|
|
if (b76(p) == 3) {
|
|
if ((p->opcode & 0x0800) != 0) {
|
|
#if Use68020
|
|
/* 11101???11mmmrrr */
|
|
p->DecOp.y.v[0].AMd = mode(p);
|
|
p->DecOp.y.v[0].ArgDat = (p->opcode >> 8) & 7;
|
|
if (0 == mode(p)) {
|
|
SetDcoArgFields(p, falseblnr, kAMdRegL, reg(p));
|
|
p->MainClass = kIKindBitField;
|
|
} else {
|
|
switch ((p->opcode >> 8) & 7) {
|
|
case 0: /* BFTST */
|
|
case 1: /* BFEXTU */
|
|
case 3: /* BFEXTS */
|
|
case 5: /* BFFFO */
|
|
if (CheckControlAddrMode(p)) {
|
|
p->MainClass = kIKindBitField;
|
|
}
|
|
break;
|
|
default: /* BFCHG, BFCLR, BFSET, BFINS */
|
|
if (CheckControlAltAddrMode(p)) {
|
|
p->MainClass = kIKindBitField;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
#else
|
|
p->MainClass = kIKindIllegal;
|
|
#endif
|
|
} else {
|
|
p->opsize = 2;
|
|
/* 11100ttd11mmmddd */
|
|
if (CheckAltMemAddrMode(p)) {
|
|
#if WantCycByPriOp
|
|
p->Cycles = (6 * kCycleScale
|
|
#if ! WantCloserCyc
|
|
+ 2 * kCycleScale
|
|
#endif
|
|
+ RdAvgXtraCyc + WrAvgXtraCyc);
|
|
p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
|
|
#endif
|
|
p->MainClass = rolops(p, rg9(p));
|
|
SetDcoArgFields(p, trueblnr, kAMdDat4, 1);
|
|
}
|
|
}
|
|
} else {
|
|
FindOpSizeFromb76(p);
|
|
if (mode(p) < 4) {
|
|
/* 1110cccdss0ttddd */
|
|
if (CheckValidAddrMode(p, 0, reg(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
p->Cycles = ((4 == p->opsize)
|
|
? (8 * kCycleScale + RdAvgXtraCyc)
|
|
: (6 * kCycleScale + RdAvgXtraCyc))
|
|
#if ! WantCloserCyc
|
|
+ (octdat(rg9(p)) * (2 * kCycleScale))
|
|
#endif
|
|
;
|
|
#endif
|
|
p->MainClass = rolops(p, mode(p) & 3);
|
|
SetDcoArgFields(p, trueblnr, kAMdDat4, octdat(rg9(p)));
|
|
}
|
|
} else {
|
|
/* 1110rrrdss1ttddd */
|
|
if (CheckValidAddrMode(p, 0, rg9(p),
|
|
kAddrValidAny, trueblnr))
|
|
if (CheckValidAddrMode(p, 0, reg(p),
|
|
kAddrValidAny, falseblnr))
|
|
{
|
|
#if WantCycByPriOp
|
|
#if WantCloserCyc
|
|
p->Cycles = ((4 == p->opsize)
|
|
? (8 * kCycleScale + RdAvgXtraCyc)
|
|
: (6 * kCycleScale + RdAvgXtraCyc));
|
|
#else
|
|
p->Cycles = (4 == p->opsize)
|
|
? ((8 * kCycleScale)
|
|
+ RdAvgXtraCyc + (8 * (2 * kCycleScale)))
|
|
/* say average shift count of 8 */
|
|
: ((6 * kCycleScale)
|
|
+ RdAvgXtraCyc + (4 * (2 * kCycleScale)));
|
|
/* say average shift count of 4 */
|
|
#endif
|
|
#endif
|
|
p->MainClass = rolops(p, mode(p) & 3);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
LOCALPROCUSEDONCE DeCodeF(WorkR *p)
|
|
{
|
|
#if WantCycByPriOp
|
|
p->Cycles =
|
|
(34 * kCycleScale + 4 * RdAvgXtraCyc + 3 * WrAvgXtraCyc);
|
|
#endif
|
|
p->DecOp.y.v[0].AMd = (p->opcode >> 8) & 0xFF;
|
|
p->DecOp.y.v[0].ArgDat = (p->opcode ) & 0xFF;
|
|
#if EmMMU || EmFPU
|
|
switch (rg9(p)) {
|
|
#if EmMMU
|
|
case 0:
|
|
p->MainClass = kIKindMMU;
|
|
break;
|
|
#endif
|
|
#if EmFPU
|
|
case 1:
|
|
switch (md6(p)) {
|
|
case 0:
|
|
p->MainClass = kIKindFPUmd60;
|
|
break;
|
|
case 1:
|
|
if (mode(p) == 1) {
|
|
p->MainClass = kIKindFPUDBcc;
|
|
} else if (mode(p) == 7) {
|
|
p->MainClass = kIKindFPUTrapcc;
|
|
} else {
|
|
p->MainClass = kIKindFPUScc;
|
|
}
|
|
break;
|
|
case 2:
|
|
p->MainClass = kIKindFPUFBccW;
|
|
break;
|
|
case 3:
|
|
p->MainClass = kIKindFPUFBccL;
|
|
break;
|
|
case 4:
|
|
p->MainClass = kIKindFPUSave;
|
|
break;
|
|
case 5:
|
|
p->MainClass = kIKindFPURestore;
|
|
break;
|
|
default:
|
|
p->MainClass = kIKindFPUdflt;
|
|
break;
|
|
}
|
|
break;
|
|
#endif
|
|
default:
|
|
p->MainClass = kIKindFdflt;
|
|
break;
|
|
}
|
|
#else
|
|
p->MainClass = kIKindFdflt;
|
|
#endif
|
|
}
|
|
|
|
LOCALPROC DeCodeOneOp(WorkR *p)
|
|
{
|
|
switch (p->opcode >> 12) {
|
|
case 0x0:
|
|
DeCode0(p);
|
|
break;
|
|
case 0x1:
|
|
DeCode1(p);
|
|
break;
|
|
case 0x2:
|
|
DeCode2(p);
|
|
break;
|
|
case 0x3:
|
|
DeCode3(p);
|
|
break;
|
|
case 0x4:
|
|
DeCode4(p);
|
|
break;
|
|
case 0x5:
|
|
DeCode5(p);
|
|
break;
|
|
case 0x6:
|
|
DeCode6(p);
|
|
break;
|
|
case 0x7:
|
|
DeCode7(p);
|
|
break;
|
|
case 0x8:
|
|
DeCode8(p);
|
|
break;
|
|
case 0x9:
|
|
DeCode9(p);
|
|
break;
|
|
case 0xA:
|
|
DeCodeA(p);
|
|
break;
|
|
case 0xB:
|
|
DeCodeB(p);
|
|
break;
|
|
case 0xC:
|
|
DeCodeC(p);
|
|
break;
|
|
case 0xD:
|
|
DeCodeD(p);
|
|
break;
|
|
case 0xE:
|
|
DeCodeE(p);
|
|
break;
|
|
case 0xF:
|
|
default: /* keep compiler happy */
|
|
DeCodeF(p);
|
|
break;
|
|
}
|
|
|
|
if (kIKindIllegal == p->MainClass) {
|
|
#if WantCycByPriOp
|
|
p->Cycles = (34 * kCycleScale
|
|
+ 4 * RdAvgXtraCyc + 3 * WrAvgXtraCyc);
|
|
#endif
|
|
p->DecOp.y.v[0].AMd = 0;
|
|
p->DecOp.y.v[0].ArgDat = 0;
|
|
p->DecOp.y.v[1].AMd = 0;
|
|
p->DecOp.y.v[1].ArgDat = 0;
|
|
}
|
|
|
|
SetDcoMainClas(&(p->DecOp), p->MainClass);
|
|
#if WantCycByPriOp
|
|
SetDcoCycles(&(p->DecOp), p->Cycles);
|
|
#else
|
|
SetDcoCycles(&(p->DecOp), kMyAvgCycPerInstr);
|
|
#endif
|
|
}
|
|
|
|
GLOBALPROC M68KITAB_setup(DecOpR *p)
|
|
{
|
|
ui5b i;
|
|
WorkR r;
|
|
|
|
for (i = 0; i < (ui5b)256 * 256; ++i) {
|
|
r.opcode = i;
|
|
r.MainClass = kIKindIllegal;
|
|
|
|
r.DecOp.y.v[0].AMd = 0;
|
|
r.DecOp.y.v[0].ArgDat = 0;
|
|
r.DecOp.y.v[1].AMd = 0;
|
|
r.DecOp.y.v[1].ArgDat = 0;
|
|
#if WantCycByPriOp
|
|
r.Cycles = kMyAvgCycPerInstr;
|
|
#endif
|
|
|
|
DeCodeOneOp(&r);
|
|
|
|
p[i] = r.DecOp;
|
|
}
|
|
}
|