918 lines
37 KiB
Plaintext
918 lines
37 KiB
Plaintext
# sleigh specification file for Intel 8051
|
|
|
|
#@define BIT_OPS "PCODEOPS"
|
|
#@define BIT_OPS "SHIFTS"
|
|
@define BIT_OPS "BIT_ADDRS"
|
|
|
|
# It's sometimes clearer for decompilation to omit the pushing and
|
|
# restoring of the return value for function calls.
|
|
#@define OMIT_RETADDR
|
|
|
|
# TODO !!! need to fully employ resultflags macro after resolving the use of the above BIT_OPS !!!
|
|
# TODO !!! Need to reconcile use of PSW vs. PSW1 for MCS251 !!!
|
|
# TODO !!! Need to fill-out SFR bits in 80251.pspec !!!
|
|
|
|
@if defined(ENDIAN)
|
|
define endian=$(ENDIAN);
|
|
@else
|
|
define endian=big;
|
|
@endif
|
|
|
|
define alignment=1;
|
|
|
|
@if defined(MCS251)
|
|
|
|
@define PTRSIZE 3
|
|
@define SP_SIZE 3
|
|
|
|
define space RAM type=ram_space size=3 default;
|
|
define space SFR type=ram_space size=2;
|
|
define space BITS type=ram_space size=2;
|
|
|
|
# 8051 spaces map to the following regions of the 80251 RAM space:
|
|
# CODE - 0xff0000-0xffffff
|
|
# EXTERNAL - 0x010000-0x01ffff
|
|
# INTERNAL - 0x000000-0x0000ff
|
|
|
|
@elif defined(MCS51)
|
|
|
|
@if defined(PTRSIZE)
|
|
@else
|
|
@define PTRSIZE 2
|
|
@endif
|
|
|
|
# SP stack pointer should be set to the size of the space it is used in, to avoid "issues"
|
|
# This is a minor inconsistency with the model and the actual processor in some cases
|
|
# If pristine SP sizing is required for rollover and such, the model should be changed
|
|
#
|
|
@define SP_SIZE 1
|
|
|
|
define space CODE type=ram_space size=$(PTRSIZE) default;
|
|
define space INTMEM type=ram_space size=1;
|
|
define space EXTMEM type=ram_space size=2;
|
|
define space SFR type=ram_space size=1;
|
|
define space BITS type=ram_space size=1;
|
|
|
|
@elif defined(MCS80390)
|
|
|
|
@define PTRSIZE 3
|
|
@define SP_SIZE 1
|
|
|
|
define space CODE type=ram_space size=3 default;
|
|
define space INTMEM type=ram_space size=1;
|
|
define space EXTMEM type=ram_space size=3;
|
|
define space SFR type=ram_space size=1;
|
|
define space BITS type=ram_space size=1;
|
|
|
|
@elif defined(MX51)
|
|
|
|
@define PTRSIZE 3
|
|
@define SP_SIZE 3
|
|
|
|
# The right thing for decompilation is to represent these
|
|
# as part of one uniform space, similar to the 80251.
|
|
# Remember to load code at 800000
|
|
#
|
|
# xdata 0 (EXTMEM)
|
|
# data 7f0000 (INTMEM)
|
|
# code 800000
|
|
|
|
define space RAM type=ram_space size=3 default;
|
|
define space SFR type=ram_space size=1;
|
|
define space ESFR type=ram_space size=1;
|
|
define space BITS type=ram_space size=1;
|
|
define space EBITS type=ram_space size=1;
|
|
|
|
# Unsure where stack really is, but probably don't want it on normal
|
|
# registers
|
|
#@define STACKBASE 0x7f0100
|
|
@define STACKBASE 0
|
|
|
|
@else
|
|
# "error Unknown processor"
|
|
@endif
|
|
|
|
|
|
|
|
define space register type=register_space size=1;
|
|
|
|
# Register File
|
|
define register offset=0x00 size=1 [ R0 R1 R2 R3 R4 R5 R6 R7 ];
|
|
|
|
# for future jump table fixup
|
|
define register offset=0x70 size=1 [ jumpTableGuard1 jumpTableGuard2 ];
|
|
|
|
@if defined(MCS251)
|
|
|
|
define register offset=0x08 size=1 [ R8 R9 B ACC R12 R13 R14 R15
|
|
R16 R17 R18 R19 R20 R21 R22 R23
|
|
R24 R25 R26 R27 R28 R29 R30 R31
|
|
];
|
|
define register offset=0x0 size=2 [ WR0 WR2 WR4 WR6 WR8 AB WR12 WR14
|
|
WR16 WR18 WR20 WR22 WR24 WR26 WR28 WR30
|
|
];
|
|
define register offset=0x0 size=4 [ DR0 DR4 DR8 DR12 DR16 DR20 DR24 DR28 ];
|
|
|
|
define register offset=0x38 size=1 [ R56 DPXL DPH DPL R60 R61 SPH ];
|
|
define register offset=0x3A size=2 [ DPTR ];
|
|
define register offset=0x38 size=4 [ DPX SPX ];
|
|
|
|
@elif defined(MCS51) || defined(MCS80390) || defined(MX51)
|
|
|
|
define register offset=0x00 size=4 [ R0R1R2R3 ];
|
|
define register offset=0x01 size=3 [ R1R2R3 ]; # Used as R3R2R1
|
|
define register offset=0x01 size=2 [ R2R1 ];
|
|
define register offset=0x00 size=2 [ R0R1 R2R3 R4R5 R6R7 ];
|
|
define register offset=0x04 size=4 [ R4R5R6R7 ];
|
|
define register offset=0x05 size=3 [ R5R6R7 ];
|
|
|
|
define register offset=0x0A size=1 [ B ACC ]; # relocated to facilitate AB 16-bit access
|
|
define register offset=0x0A size=2 [ AB ];
|
|
|
|
@if defined(MCS51) || defined(MX51)
|
|
define register offset=0x82 size=2 [ DPTR ];
|
|
define register offset=0x82 size=1 [ DPH DPL ]; # relocated to facilitate DPTR 16-bit access
|
|
@elif defined(MCS80390)
|
|
|
|
# Following existing example, relocated DPX, DPH, and DPL for DPTR
|
|
# access. Rework some direct moves to compensate. Not clear that all
|
|
# cases are covered, thus might be problematic hack in the long term.
|
|
define register offset=0x82 size=3 [ DPTR ];
|
|
define register offset=0x82 size=1 [ DPX DPH DPL ];
|
|
@endif
|
|
|
|
@else
|
|
# "error Unknown processor"
|
|
@endif
|
|
|
|
|
|
define register offset=0x40 size=$(SP_SIZE) [ SP ];
|
|
define register offset=0x44 size=$(PTRSIZE) [ PC ];
|
|
define register offset=0x48 size=1 [ PSW ];
|
|
@if defined(DUAL_DPTR)
|
|
# Dual DPTR
|
|
# Rather than model it as context, we're just going
|
|
# to special case the INC and DEC instructions
|
|
# to swap the register values
|
|
define register offset=0x4a size=2 [ DPTR2 ];
|
|
define register offset=$(DPS_REG_NUM) size=1 [ AUXR1 ]; # Bit 0 is DPS
|
|
@endif
|
|
|
|
@define CY "PSW[7,1]"
|
|
@define AC "PSW[6,1]"
|
|
@define N "PSW[5,1]"
|
|
@define RS1 "PSW[4,1]"
|
|
@define RS0 "PSW[3,1]"
|
|
@define OV "PSW[2,1]"
|
|
@define Z "PSW[1,1]"
|
|
|
|
@if defined(MX51)
|
|
# remap these into the normal register file for decompiler use.
|
|
# Really belong on ESFR @0xfc - 0xfe with order EPL EPM EPH
|
|
define register offset=0xc0 size=1 [ EPH EPM EPL ];
|
|
define register offset=0xc0 size=3 [ EPTR ];
|
|
@endif
|
|
|
|
@if defined(MCS251)
|
|
|
|
define register offset=0x50 size=4 contextReg;
|
|
|
|
define context contextReg
|
|
phase = (0,0)
|
|
srcMode = (1,1) # (reflects UCONFIG0.0) 1: source mode, 0: binary mode
|
|
A5Prefix = (2,2) # reflects presence of A5 prefix
|
|
;
|
|
|
|
# GROUP1 - MCS51 instructions in 0x00-0x5F range
|
|
@define GROUP1 "epsilon"
|
|
|
|
# GROUP2 - MCS51 instructions in 0x60-0xff range
|
|
@define GROUP2 "((srcMode=0 & A5Prefix=0) | (srcMode=1 & A5Prefix=1))"
|
|
|
|
# GROUP3 - MCS251 instructions in 0x60-0xff range
|
|
@define GROUP3 "((srcMode=0 & A5Prefix=1) | (srcMode=1 & A5Prefix=0))"
|
|
|
|
@elif defined(MCS51) || defined(MCS80390) || defined(MX51)
|
|
|
|
@define GROUP1 "epsilon"
|
|
@define GROUP2 "epsilon"
|
|
@define GROUP3 "epsilon"
|
|
|
|
@endif
|
|
|
|
define pcodeop decimal_adjust;
|
|
define pcodeop nop;
|
|
|
|
@if BIT_OPS == "PCODEOPS"
|
|
define pcodeop get;
|
|
define pcodeop set;
|
|
define pcodeop set_bit_value;
|
|
define pcodeop clr;
|
|
@endif
|
|
|
|
|
|
#TOKENS
|
|
|
|
define token opbyte (8)
|
|
opfull = (0,7)
|
|
oplo = (0,3)
|
|
ophi = (4,7)
|
|
rn = (0,2)
|
|
rnfill = (3,3)
|
|
ri = (0,0)
|
|
rifill = (1,3)
|
|
opaddr = (5,7)
|
|
addrfill = (4,4)
|
|
|
|
b_0000 = (0,0)
|
|
b_0001 = (0,1)
|
|
b_0002 = (0,2)
|
|
b_0005 = (0,5)
|
|
b_0101 = (1,1)
|
|
b_0107 = (1,7)
|
|
b_0207 = (2,7)
|
|
b_0307 = (3,7)
|
|
b_0607 = (6,7)
|
|
@if defined(MX51)
|
|
PRi_sel = (2,2)
|
|
PRi_revend = (2,2) # reverse endian
|
|
emov_delta = (0,1)
|
|
@endif
|
|
;
|
|
define token AddrByte (8)
|
|
direct = (0,7)
|
|
bank = (7,7)
|
|
sfr = (0,6)
|
|
sfr6 = (6,6)
|
|
sfrlo = (0,3)
|
|
mainreg = (0,6)
|
|
direct17 = (1,7)
|
|
;
|
|
define token AddrByte2 (8)
|
|
direct2 = (0,7)
|
|
bank2 = (7,7)
|
|
sfr2 = (0,6)
|
|
sfr26 = (6,6)
|
|
sfr2lo = (0,3)
|
|
mainreg2 = (0,6)
|
|
;
|
|
define token BitByte (8)
|
|
bitaddr8 = (0,7)
|
|
bitaddr27 = (2,7)
|
|
bitbank = (7,7)
|
|
sfrbyte = (3,7)
|
|
bitaddr57 = (5,7)
|
|
sfrbit6 = (6,6)
|
|
sfrbit3 = (3,3)
|
|
sfrbit = (0,2) dec
|
|
lowbyte = (3,6)
|
|
bitaddr0 = (0,0)
|
|
;
|
|
define token AddrTwo (16)
|
|
addr16 = (0,15)
|
|
;
|
|
@if defined(MCS80390)
|
|
# todo: deconflict with 80251 version
|
|
define token AddrThree (24)
|
|
addr24 = (0,23)
|
|
;
|
|
@endif
|
|
|
|
define token RelByte (8) rel8=(0,7) signed;
|
|
define token ImmedByte (8) data=(0,7);
|
|
define token ImmedTwo (16)
|
|
data16 = (0,15)
|
|
rel16 = (0,15) signed
|
|
;
|
|
@if defined(MCS80390)
|
|
define token ImmedThree (24)
|
|
data24 = (0,23)
|
|
;
|
|
@endif
|
|
|
|
@if defined(MCS80390)
|
|
define token aopword (24)
|
|
aoplo = (16,19)
|
|
aopaddr = (21,23)
|
|
aaddrfill = (20,20)
|
|
adata = (0,15)
|
|
;
|
|
@else
|
|
define token aopword (16)
|
|
aoplo = (8,11)
|
|
aopaddr = (13,15)
|
|
aaddrfill = (12,12)
|
|
adata = (0,7)
|
|
;
|
|
@endif
|
|
|
|
attach variables rn [ R0 R1 R2 R3 R4 R5 R6 R7 ];
|
|
attach variables ri [ R0 R1 ];
|
|
|
|
# flags macros
|
|
|
|
#macro addflags(op1, op2) { # Flags set by add instructions
|
|
# PSW = PSW & 0x7b;
|
|
# PSW = PSW | (carry(op1,op2)<<7) # Check for carry
|
|
# | (scarry(op1,op2)<<2); # Check for signed carry
|
|
#}
|
|
|
|
#macro subflags(op1, op2) { # Flags set by sub instructions
|
|
# PSW = PSW & 0x7b;
|
|
# PSW = PSW | ((op1<op2)<<7) # Check for borrow
|
|
# | (sborrow(op1,op2)<<2); # Check for signed borrow
|
|
#}
|
|
|
|
#macro compflags(op1, op2) { # Flags set by the compare instructions
|
|
# PSW = PSW & 0x7f;
|
|
# PSW = PSW | ((op1 < op2) << 7);
|
|
#}
|
|
|
|
macro addflags(op1, op2) { # Flags set by add instructions
|
|
$(CY) = (carry(op1,op2)); # Check for carry
|
|
#OV = (scarry(op1,op2)); # Check for signed carry
|
|
}
|
|
|
|
macro subflags(op1, op2) { # Flags set by sub instructions
|
|
$(CY) = (op1 < op2); # Check for carry
|
|
#OV = sborrow(op1,op2); # Check for signed carry
|
|
}
|
|
|
|
macro compflags(op1, op2) { # Flags set by the compare instructions
|
|
$(CY) = (op1 < op2); # Check for carry
|
|
}
|
|
|
|
macro resultflags(op1) { # Set N,Z flag for results
|
|
$(N) = op1 s< 0;
|
|
$(Z) = op1 == 0;
|
|
}
|
|
|
|
macro push8(val) {
|
|
@if defined(MCS251)
|
|
SPX = SPX + 1;
|
|
ptr:3 = SPX:3;
|
|
*[RAM]:1 ptr = val;
|
|
@elif defined(MCS51) || defined(MCS80390)
|
|
SP = SP + 1;
|
|
*[INTMEM]:1 SP = val;
|
|
@elif defined(MX51)
|
|
SP = SP + 1;
|
|
#tmp:3 = zext(SP) + $(STACKBASE);
|
|
tmp:3 = SP;
|
|
*[RAM]:1 tmp = val;
|
|
@else
|
|
val = val;
|
|
@endif
|
|
}
|
|
|
|
@ifdef OMIT_RETADDR
|
|
@ifdef MCS80390
|
|
macro push24(val) { val = val; }
|
|
@else
|
|
macro push16(val) { val = val; }
|
|
@endif
|
|
|
|
@else
|
|
# Want to model pushes
|
|
@ifndef MCS80390
|
|
macro push16(val) {
|
|
@if defined(MCS251)
|
|
al:1 = val:1;
|
|
ah:1 = val(1);
|
|
|
|
SPX = SPX + 1;
|
|
*[RAM]:1 SPX:3 = al;
|
|
SPX = SPX + 1;
|
|
*[RAM]:1 SPX:3 = ah;
|
|
|
|
@elif defined(MCS51)
|
|
al:1 = val:1;
|
|
ah:1 = val(1);
|
|
|
|
SP = SP + 1;
|
|
*[INTMEM]:1 SP = al;
|
|
SP = SP + 1;
|
|
*[INTMEM]:1 SP = ah;
|
|
|
|
@elif defined(MX51)
|
|
# dptr push
|
|
#ptr:1 = SP + 1;
|
|
#tmp:3 = zext(ptr) + $(STACKBASE);
|
|
|
|
al:1 = val:1;
|
|
ah:1 = val(1);
|
|
|
|
SP = SP + 1;
|
|
*[RAM]:1 SP = al;
|
|
SP = SP + 1;
|
|
*[RAM]:1 SP = ah;
|
|
@else
|
|
val = val;
|
|
@endif
|
|
}
|
|
@else
|
|
#@if defined(MCS80390)
|
|
macro push24(val) {
|
|
al:1 = val:1;
|
|
ah:1 = val(1);
|
|
ax:1 = val(2);
|
|
|
|
SP = SP + 1;
|
|
*[INTMEM]:1 SP = al;
|
|
SP = SP + 1;
|
|
*[INTMEM]:1 SP = ah;
|
|
SP = SP + 1;
|
|
*[INTMEM]:1 SP = ax;
|
|
}
|
|
@endif
|
|
@endif
|
|
|
|
macro pop8(val) {
|
|
@if defined(MCS251)
|
|
ptr:3 = SPX:3;
|
|
val = *[RAM]:1 ptr;
|
|
SPX = SPX - 1;
|
|
@elif defined(MCS51) || defined(MCS80390)
|
|
val = *[INTMEM]:1 SP;
|
|
SP = SP - 1;
|
|
@elif defined(MX51)
|
|
#ptr:3 = zext(SP) + $(STACKBASE);
|
|
ptr:3 = SP;
|
|
val = *[RAM]:1 ptr;
|
|
SP = SP - 1;
|
|
@else
|
|
val = val;
|
|
@endif
|
|
}
|
|
|
|
@if defined(MCS80390)
|
|
@ifdef OMIT_RETADDR
|
|
macro pop24(val) { val = val; }
|
|
@else
|
|
macro pop24(val) {
|
|
ptr:1 = SP - 2;
|
|
al : 1 = *[INTMEM]:1 ptr;
|
|
ah : 1 = *[INTMEM]:1 (ptr+1);
|
|
ax : 1 = *[INTMEM]:1 (ptr+2);
|
|
bl:3 = zext(al);
|
|
bh:3 = zext(ah) << 8;
|
|
bx:3 = zext(ax) << 16;
|
|
z : 3 = bl;
|
|
z = (z | bh);
|
|
z = (z | bx);
|
|
val = z;
|
|
SP = ptr - 1;
|
|
}
|
|
@endif
|
|
@else
|
|
@ifdef OMIT_RETADDR
|
|
macro pop16(val) { val = val; }
|
|
@else
|
|
macro pop16(val) {
|
|
@if defined(MCS251)
|
|
|
|
ah:1 = *:1 SPX:$(SP_SIZE);
|
|
SPX = SPX - 1;
|
|
al:1 = *:1 SPX:$(SP_SIZE);
|
|
SPX = SPX - 1;
|
|
|
|
val = (zext(ah) << 8) | zext(al);
|
|
|
|
@elif defined(MCS51)
|
|
|
|
ah:1 = *[INTMEM]:1 SP;
|
|
SP = SP - 1;
|
|
al:1 = *[INTMEM]:1 SP;
|
|
SP = SP - 1;
|
|
|
|
val = (zext(ah) << 8) | zext(al);
|
|
|
|
@elif defined(MX51)
|
|
|
|
ah:1 = *[RAM]:1 SP;
|
|
SP = SP - 1;
|
|
al:1 = *[RAM]:1 SP;
|
|
SP = SP - 1;
|
|
|
|
val = (zext(ah) << 8) | zext(al);
|
|
@else
|
|
val = val;
|
|
@endif
|
|
}
|
|
@endif
|
|
@endif
|
|
|
|
|
|
# Operand display only
|
|
CY: "CY" is epsilon { }
|
|
|
|
Areg: "A" is ophi { export ACC; }
|
|
ABreg: AB is ophi & AB { export AB; }
|
|
DPTRreg: DPTR is ophi & DPTR { export DPTR; }
|
|
|
|
@if defined(MCS251)
|
|
ADPTR: "@A+"^DPTR is ophi & DPTR { ptr:3 = 0xff0000 + zext(DPTR) + zext(ACC); export ptr; }
|
|
@elif defined(MCS51)
|
|
ADPTR: "@A+"^DPTR is ophi & DPTR { ptr:$(PTRSIZE) = zext(DPTR) + zext(ACC); export ptr; }
|
|
@elif defined(MCS80390)
|
|
ADPTR: "@A+"^DPTR is ophi & DPTR { ptr:3 = zext(DPTR) + zext(ACC); export ptr; }
|
|
@elif defined(MX51)
|
|
ADPTR: "@A+"^DPTR is ophi & DPTR { ptr:3 = 0x800000 + zext(DPTR) + zext(ACC); export ptr; }
|
|
@endif
|
|
|
|
APC: "@A+PC" is epsilon { tmp:$(PTRSIZE) = inst_next + zext(ACC); export tmp; }
|
|
|
|
@if defined(MCS251)
|
|
ATDPTR: "@"^DPTR is ophi & DPTR { ptr:3 = 0x010000 + zext(DPTR); export *:1 ptr; } # 8051 External data address mapped into RAM space
|
|
@elif defined(MCS51)
|
|
ATDPTR: "@"^DPTR is ophi & DPTR { ptr:2 = DPTR; export *[EXTMEM]:1 ptr; }
|
|
@elif defined(MCS80390)
|
|
ATDPTR: "@"^DPTR is ophi & DPTR { ptr:3 = zext(DPTR); export *[EXTMEM]:1 ptr; }
|
|
@elif defined(MX51)
|
|
ATDPTR: "@"^DPTR is ophi & DPTR { ptr:3 = zext(DPTR); export *[RAM]:1 ptr; }
|
|
@endif
|
|
|
|
@if defined(MCS251)
|
|
Ri: @ri is ri { ptr:3 = zext(ri); export *[RAM]:1 ptr; }
|
|
@elif defined(MX51)
|
|
Ri: @ri is ri { ptr:3 = zext(ri) + 0x7f0000; export *[RAM]:1 ptr; }
|
|
@elif defined(MCS51) || defined(MCS80390)
|
|
Ri: @ri is ri { export *[INTMEM]:1 ri; }
|
|
@endif
|
|
|
|
@if defined(MCS251)
|
|
RiX: @ri is ri { ptr:3 = 0x010000 + zext(ri); export *:1 ptr; } # 8051 8-bit External data address mapped into RAM space
|
|
@elif defined(MCS51)
|
|
RiX: @ri is ri { ptr:2 = zext(ri); export *[EXTMEM]:1 ptr; } # limited to 8-bit external data address (I/O state can be used to produce 16-bit addr)
|
|
@elif defined(MCS80390)
|
|
RiX: @ri is ri { ptr:3 = zext(ri); export *[EXTMEM]:1 ptr; } # tocheck
|
|
@elif defined(MX51)
|
|
RiX: @ri is ri { ptr:3 = zext(ri); export *[RAM]:1 ptr; }
|
|
@endif
|
|
|
|
Data: "#"data is data { export *[const]:1 data; }
|
|
Data16: "#"data16 is data16 { export *[const]:2 data16; }
|
|
@if defined(MCS80390)
|
|
Data24: "#"data24 is data24 { export *[const]:3 data24; }
|
|
@endif
|
|
|
|
@if defined(MCS251)
|
|
Direct: mainreg is bank=0 & mainreg { export *[RAM]:1 mainreg; }
|
|
@elif defined(MX51)
|
|
Direct: mainreg is bank=0 & mainreg { tmp:3 = mainreg + 0x7f0000; export *[RAM]:1 tmp; }
|
|
@elif defined(MCS51) || defined(MCS80390)
|
|
Direct: mainreg is bank=0 & mainreg { export *[INTMEM]:1 mainreg; }
|
|
@endif
|
|
Direct: direct is bank=1 & direct { export *[SFR]:1 direct; }
|
|
Direct: PSW is bank=1 & direct=0xD0 & PSW { export PSW; }
|
|
Direct: "A" is bank=1 & direct=0xE0 { export ACC; }
|
|
Direct: B is bank=1 & direct=0xF0 & B { export B; }
|
|
Direct: DPL is bank=1 & direct=0x82 & DPL { export DPL; }
|
|
Direct: DPH is bank=1 & direct=0x83 & DPH { export DPH; }
|
|
@if defined(MCS80390)
|
|
Direct: DPX is bank=1 & direct=0x93 & DPX { export DPX; }
|
|
@endif
|
|
@if defined(MCS251)
|
|
Direct: DPXL is bank=1 & direct=0x84 & DPXL { export DPXL; }
|
|
@endif
|
|
|
|
@if defined(MCS251)
|
|
Direct2: mainreg2 is bank2=0 & mainreg2 { export *[RAM]:1 mainreg2; }
|
|
@elif defined(MX51)
|
|
Direct2: mainreg2 is bank2=0 & mainreg2 { tmp:3 = mainreg2 + 0x7f0000; export *[RAM]:1 tmp; }
|
|
@elif defined(MCS51) || defined(MCS80390)
|
|
Direct2: mainreg2 is bank2=0 & mainreg2 { export *[INTMEM]:1 mainreg2; }
|
|
@endif
|
|
Direct2: direct2 is bank2=1 & direct2 { export *[SFR]:1 direct2; }
|
|
Direct2: PSW is bank2=1 & direct2=0xD0 & PSW { export PSW; }
|
|
Direct2: "A" is bank2=1 & direct2=0xE0 { export ACC; }
|
|
Direct2: B is bank2=1 & direct2=0xF0 & B { export B; }
|
|
Direct2: DPL is bank2=1 & direct2=0x82 & DPL { export DPL; }
|
|
Direct2: DPH is bank2=1 & direct2=0x83 & DPH { export DPH; }
|
|
@if defined(MCS80390)
|
|
Direct2: DPX is bank2=1 & direct2=0x93 & DPX { export DPX; }
|
|
@endif
|
|
@if defined(MCS251)
|
|
Direct2: DPXL is bank2=1 & direct2=0x84 & DPXL { export DPXL; }
|
|
@endif
|
|
|
|
@if defined(MCS251)
|
|
BitAddr: bitaddr is bitbank=1 & sfrbyte & sfrbit [ bitaddr =(sfrbyte << 6)+sfrbit; ] { export *[BITS]:1 bitaddr; }
|
|
BitAddr: bitaddr is bitbank=0 & lowbyte & sfrbit [ bitaddr =(lowbyte << 3)+sfrbit; ] { export *[BITS]:1 bitaddr; }
|
|
BitAddr2: "/"bitaddr is bitbank=1 & sfrbyte & sfrbit [ bitaddr =(sfrbyte << 6)+sfrbit; ] { export *[BITS]:1 bitaddr; }
|
|
BitAddr2: "/"bitaddr is bitbank=0 & lowbyte & sfrbit [ bitaddr =(lowbyte << 3)+sfrbit; ] { export *[BITS]:1 bitaddr; }
|
|
@elif defined(MCS51) || defined(MCS80390) || defined(MX51)
|
|
##
|
|
##TODO !!! 8051 SFRBITS bit overlay block is probably incorrect since there is not a 1:1 mapping to the SFR space
|
|
## While the BitAddr is only used for disassembly markup, and labels come from pspec, the underlying data will
|
|
## not map correctly. We could switch completely to the full SFR bit mapping as done above for the 80251.
|
|
## This would require a change in the BITS space size.
|
|
##
|
|
BitAddr: bitaddr is bitbank=1 & sfrbyte & sfrbit [ bitaddr =(sfrbyte << 3)+sfrbit; ] { export *[BITS]:1 bitaddr; }
|
|
BitAddr: bitaddr is bitbank=0 & lowbyte & sfrbit [ bitaddr =(lowbyte << 3)+sfrbit; ] { export *[BITS]:1 bitaddr; }
|
|
BitAddr2: "/"bitaddr is bitbank=1 & sfrbyte & sfrbit [ bitaddr =(sfrbyte << 3)+sfrbit; ] { export *[BITS]:1 bitaddr; }
|
|
BitAddr2: "/"bitaddr is bitbank=0 & lowbyte & sfrbit [ bitaddr =(lowbyte << 3)+sfrbit; ] { export *[BITS]:1 bitaddr; }
|
|
@endif
|
|
|
|
BitByteAddr: byteaddr is bitbank=1 & sfrbyte & sfrbit [ byteaddr =(sfrbyte << 3); ] { export *[SFR]:1 byteaddr; }
|
|
BitByteAddr: "A" is bitbank=1 & sfrbyte=0x1C & sfrbit { export ACC; }
|
|
BitByteAddr: B is bitbank=1 & sfrbyte=0x1E & sfrbit & B { export B; }
|
|
BitByteAddr: PSW is bitbank=1 & sfrbyte=0x1A & sfrbit & PSW { export PSW; }
|
|
@if defined(MCS251)
|
|
BitByteAddr: byteaddr is bitbank=0 & lowbyte & sfrbit [ byteaddr = lowbyte + 0x20; ] { export *[RAM]:1 byteaddr; }
|
|
@elif defined(MX51)
|
|
BitByteAddr: byteaddr is bitbank=0 & lowbyte & sfrbit [ byteaddr = lowbyte + 0x20; ] { tmp:3 = byteaddr + 0x7f0000; export *[RAM]:1 tmp; }
|
|
@elif defined(MCS51) || defined(MCS80390)
|
|
BitByteAddr: byteaddr is bitbank=0 & lowbyte & sfrbit [ byteaddr = lowbyte + 0x20; ] { export *[INTMEM]:1 byteaddr; }
|
|
@endif
|
|
|
|
@if defined(MCS251) || defined(MX51)
|
|
Addr11: relAddr is aopaddr & adata [ relAddr = (inst_next $and 0xfff800)+(aopaddr*256)+adata; ] { export *:1 relAddr; }
|
|
Addr16: addr is addr16 [ addr = (inst_next $and 0xff0000) + addr16; ] { export *:1 addr; }
|
|
@elif defined(MCS51)
|
|
Addr11: relAddr is aopaddr & adata [ relAddr =(inst_next $and 0xf800)+(aopaddr*256)+adata; ] { export *:1 relAddr; }
|
|
Addr16: addr16 is addr16 { export *:1 addr16; }
|
|
@elif defined(MCS80390)
|
|
Addr19: relAddr is aopaddr & adata [ relAddr =(inst_next $and 0xf80000)+(aopaddr*256*256)+adata; ] { export *:1 relAddr; }
|
|
Addr24: addr24 is addr24 { export *:1 addr24; }
|
|
@endif
|
|
|
|
Rel8: relAddr is rel8 [ relAddr=inst_next+rel8; ] { export *:1 relAddr; }
|
|
Rel16: relAddr is rel16 [ relAddr=inst_next+rel16; ] { export *:1 relAddr; }
|
|
|
|
@if defined(MCS251)
|
|
# detect A5 prefix
|
|
:^instruction is phase=0 & ophi=0xa & oplo=0x5; instruction [ phase=1; A5Prefix=1; ] { }
|
|
:^instruction is phase=0 & instruction [ phase=1; A5Prefix=0; ] { }
|
|
@endif
|
|
|
|
@if defined(MCS80390)
|
|
:ACALL Addr19 is $(GROUP1) & aaddrfill=1 & aoplo=1 & Addr19 { ret:3 = inst_next; push24(ret); call Addr19; }
|
|
@else
|
|
:ACALL Addr11 is $(GROUP1) & aaddrfill=1 & aoplo=1 & Addr11 { ret:2 = inst_next; push16(ret); call Addr11; }
|
|
@endif
|
|
|
|
:ADD Areg,rn is $(GROUP2) & ophi=2 & Areg & rnfill=1 & rn { addflags(ACC,rn); ACC = ACC + rn; resultflags(ACC); }
|
|
:ADD Areg,Direct is $(GROUP1) & ophi=2 & oplo=5 & Areg; Direct { addflags(ACC,Direct); ACC = ACC + Direct; resultflags(ACC); }
|
|
:ADD Areg,Ri is $(GROUP2) & ophi=2 & Areg & rifill=3 & Ri { addflags(ACC,Ri); ACC = ACC + Ri; resultflags(ACC); }
|
|
:ADD Areg,Data is $(GROUP1) & ophi=2 & oplo=4 & Areg; Data { addflags(ACC,Data); ACC = ACC + Data; resultflags(ACC); }
|
|
|
|
:ADDC Areg,rn is $(GROUP2) & ophi=3 & Areg & rnfill=1 & rn { tmp:1 =$(CY)+ rn; addflags(ACC,tmp); ACC = ACC + tmp; resultflags(ACC); }
|
|
:ADDC Areg,Direct is $(GROUP1) & ophi=3 & oplo=5 & Areg; Direct { tmp:1 =$(CY)+ Direct; addflags(ACC,tmp); ACC = ACC + tmp; resultflags(ACC); }
|
|
:ADDC Areg,Ri is $(GROUP2) & ophi=3 & Areg & rifill=3 & Ri { tmp:1 =$(CY)+ Ri; addflags(ACC,tmp); ACC = ACC + tmp; resultflags(ACC); }
|
|
:ADDC Areg,Data is $(GROUP1) & ophi=3 & oplo=4 & Areg; Data { tmp:1 =$(CY)+ Data; addflags(ACC,tmp); ACC = ACC + tmp; resultflags(ACC); }
|
|
|
|
#TODO: which GROUP does AJMP belong to ??
|
|
@if defined(MCS80390)
|
|
:AJMP Addr19 is $(GROUP1) & aaddrfill=0 & aoplo=1 & Addr19 { goto Addr19; }
|
|
@else
|
|
:AJMP Addr11 is $(GROUP1) & aaddrfill=0 & aoplo=1 & Addr11 { goto Addr11; }
|
|
@endif
|
|
|
|
:ANL Areg,rn is $(GROUP2) & ophi=5 & Areg & rnfill=1 & rn { ACC = ACC & rn; resultflags(ACC); }
|
|
:ANL Areg,Direct is $(GROUP1) & ophi=5 & oplo=5 & Areg; Direct { ACC = ACC & Direct; resultflags(ACC); }
|
|
:ANL Areg,Ri is $(GROUP2) & ophi=5 & Areg & rifill=3 & Ri { ACC = ACC & Ri; resultflags(ACC); }
|
|
:ANL Areg,Data is $(GROUP2) & ophi=5 & oplo=4 & Areg; Data { ACC = ACC & Data; resultflags(ACC); }
|
|
:ANL Direct,Areg is $(GROUP1) & ophi=5 & oplo=2 & Areg; Direct { tmp:1 = Direct & ACC; Direct = tmp; resultflags(tmp); }
|
|
:ANL Direct,Data is $(GROUP1) & ophi=5 & oplo=3; Direct; Data { tmp:1 = Direct & Data; Direct = tmp; resultflags(tmp); }
|
|
|
|
:ANL CY,BitAddr is $(GROUP1) & CY & ophi=8 & oplo=2; BitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr {tmp:1 = BitByteAddr; $(CY)=$(CY)& ((tmp>>sfrbit)&1); resultflags(tmp); }
|
|
:ANL CY,BitAddr2 is $(GROUP1) & CY & ophi=11 & oplo=0; BitAddr2 & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr {tmp:1 = BitByteAddr; $(CY)=$(CY)& (~((tmp>>sfrbit)&1)); }
|
|
@if BIT_OPS == "BIT_ADDRS"
|
|
:ANL CY,BitAddr is $(GROUP1) & CY & ophi=8 & oplo=2; BitAddr & sfrbit & BitByteAddr {$(CY)=$(CY)& BitAddr; }
|
|
:ANL CY,BitAddr2 is $(GROUP1) & CY & ophi=11 & oplo=0; BitAddr2 & sfrbit & BitByteAddr {$(CY)=$(CY)& ~BitAddr2; }
|
|
@elif BIT_OPS == "PCODEOPS"
|
|
:ANL CY,BitAddr is $(GROUP1) & CY & ophi=8 & oplo=2; BitAddr & sfrbit & BitByteAddr {$(CY)=$(CY)& get(BitAddr, BitByteAddr); }
|
|
:ANL CY,BitAddr2 is $(GROUP1) & CY & ophi=11 & oplo=0; BitAddr2 & sfrbit & BitByteAddr {$(CY)=$(CY)& (get(BitAddr2, BitByteAddr)^1); }
|
|
@elif BIT_OPS == "SHIFTS"
|
|
:ANL CY,BitAddr is $(GROUP1) & CY & ophi=8 & oplo=2; BitAddr & sfrbit & BitByteAddr {$(CY)=$(CY)& ((BitByteAddr>>sfrbit)&1); }
|
|
:ANL CY,BitAddr2 is $(GROUP1) & CY & ophi=11 & oplo=0; BitAddr2 & sfrbit & BitByteAddr {$(CY)=$(CY)& (~((BitByteAddr>>sfrbit)&1)); }
|
|
@endif
|
|
|
|
:CJNE Areg,Direct,Rel8 is $(GROUP1) & ophi=11 & oplo=5 & Areg; Direct; Rel8 { compflags(ACC,Direct); if (ACC!=Direct) goto Rel8; }
|
|
:CJNE Areg,Data,Rel8 is $(GROUP1) & ophi=11 & oplo=4 & Areg; Data; Rel8 { compflags(ACC,Data); if (ACC!=Data) goto Rel8; }
|
|
:CJNE rn,Data,Rel8 is $(GROUP2) & ophi=11 & rnfill=1 & rn; Data; Rel8 { compflags(rn,Data); if (rn!=Data) goto Rel8; }
|
|
:CJNE Ri,Data,Rel8 is $(GROUP2) & ophi=11 & rifill=3 & Ri; Data; Rel8 { compflags(Ri,Data); if (Ri!=Data) goto Rel8; }
|
|
|
|
:CLR Areg is $(GROUP1) & ophi=14 & oplo=4 & Areg { ACC = 0; }
|
|
:CLR CY is $(GROUP1) & CY & ophi=12 & oplo=3 {$(CY)= 0; }
|
|
|
|
:CLR BitAddr is $(GROUP1) & ophi=12 & oplo=2; BitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr { local tmp = ~(1<<sfrbit); BitByteAddr = BitByteAddr & tmp; }
|
|
@if BIT_OPS == "BIT_ADDRS"
|
|
:CLR BitAddr is $(GROUP1) & ophi=12 & oplo=2; BitAddr & sfrbit & BitByteAddr { BitAddr = 0; }
|
|
@elif BIT_OPS == "PCODEOPS"
|
|
:CLR BitAddr is $(GROUP1) & ophi=12 & oplo=2; BitAddr & sfrbit & BitByteAddr { BitByteAddr = clr(BitAddr, BitByteAddr); }
|
|
#:CLR PortBit is $(GROUP1) & ophi=12 & oplo=2; PortBit & sfrbit & BitByteAddr { outp(PortBit, 0:1, BitByteAddr); }
|
|
@elif BIT_OPS == "SHIFTS"
|
|
:CLR BitAddr is $(GROUP1) & ophi=12 & oplo=2; BitAddr & sfrbit & BitByteAddr { local tmp = ~(1<<sfrbit); BitByteAddr = BitByteAddr & tmp; }
|
|
@endif
|
|
|
|
:CPL Areg is $(GROUP2) & ophi=15 & oplo=4 & Areg { ACC = ~ACC; }
|
|
:CPL CY is $(GROUP2) & CY & ophi=11 & oplo=3 {$(CY)=$(CY)^ 1; }
|
|
|
|
:CPL BitAddr is $(GROUP1) & ophi=11 & oplo=2; BitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr { tmp:1 = (1<<sfrbit); BitByteAddr = BitByteAddr ^ tmp; }
|
|
@if BIT_OPS == "BIT_ADDRS"
|
|
:CPL BitAddr is $(GROUP1) & ophi=11 & oplo=2; BitAddr & sfrbit & BitByteAddr { BitAddr = BitAddr ^ 1; }
|
|
@elif BIT_OPS == "PCODEOPS"
|
|
:CPL BitAddr is $(GROUP1) & ophi=11 & oplo=2; BitAddr & sfrbit & BitByteAddr { tmp:1 = get(BitAddr, BitByteAddr) ^ 1; BitByteAddr = set_bit_value(BitAddr, tmp, BitByteAddr); }
|
|
@elif BIT_OPS == "SHIFTS"
|
|
:CPL BitAddr is $(GROUP1) & ophi=11 & oplo=2; BitAddr & sfrbit & BitByteAddr { tmp:1 = (1<<sfrbit); BitByteAddr = BitByteAddr ^ tmp; }
|
|
@endif
|
|
|
|
:DA Areg is $(GROUP1) & ophi=13 & oplo=4 & Areg { ACC = decimal_adjust(ACC); }
|
|
|
|
:DEC Areg is $(GROUP1) & ophi=1 & oplo=4 & Areg { ACC = ACC - 1; }
|
|
:DEC rn is $(GROUP2) & ophi=1 & rnfill=1 & rn { rn = rn - 1; }
|
|
:DEC Direct is $(GROUP1) & ophi=1 & oplo=5; Direct { Direct = Direct - 1; }
|
|
:DEC Ri is $(GROUP2) & ophi=1 & rifill=3 & Ri { Ri = Ri - 1; }
|
|
|
|
:DIV ABreg is $(GROUP1) & ophi=8 & oplo=4 & ABreg { PSW = PSW & 0x7b; tmp : 1 = (B == 0)<<2; PSW = PSW | tmp; if (B==0) goto inst_next; tmp2 : 1 = ACC; ACC = tmp2 / B; B = tmp2 % B; }
|
|
|
|
# Specifying rnfill here is a temporary to allow distinguishing DJNZ1 and XCHD
|
|
:DJNZ rn,Rel8 is $(GROUP2) & ophi=13 & rnfill=1 & rnfill=1 & rn; Rel8 { rn = rn - 1; if (rn!=0) goto Rel8; }
|
|
:DJNZ Direct,Rel8 is $(GROUP1) & ophi=13 & oplo=5; Direct; Rel8 { Direct = Direct - 1; if (Direct!=0) goto Rel8; }
|
|
|
|
:INC Areg is $(GROUP1) & ophi=0 & oplo=4 & Areg { ACC = ACC + 1; }
|
|
:INC rn is $(GROUP2) & ophi=0 & rnfill=1 & rn { rn = rn + 1; }
|
|
:INC Direct is $(GROUP1) & ophi=0 & oplo=5; Direct { Direct = Direct + 1; }
|
|
@if defined(DUAL_DPTR) && defined(DPS_REG_NUM)
|
|
:INC Direct is $(GROUP1) & ophi=0 & oplo=5; Direct & direct=$(DPS_REG_NUM) {
|
|
AUXR1 = AUXR1 ^ 0x01;
|
|
tmp:2 = DPTR;
|
|
DPTR = DPTR2;
|
|
DPTR2 = tmp;
|
|
}
|
|
@endif
|
|
:INC Ri is $(GROUP2) & ophi=0 & rifill=3 & Ri { Ri = Ri + 1; }
|
|
:INC DPTRreg is $(GROUP1) & ophi=10 & oplo=3 & DPTRreg { DPTR = DPTR + 1; }
|
|
|
|
:JB BitAddr,Rel8 is $(GROUP1) & ophi=2 & oplo=0; BitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr; Rel8 { if (((BitByteAddr>>sfrbit)&1) == 1:1) goto Rel8; }
|
|
:JBC BitAddr,Rel8 is $(GROUP1) & ophi=1 & oplo=0; BitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr; Rel8 { tmp:1 = 1<<sfrbit; if ((BitByteAddr & tmp)==0) goto inst_next; BitByteAddr = BitByteAddr & ~tmp; goto Rel8; }
|
|
@if BIT_OPS == "BIT_ADDRS"
|
|
:JB BitAddr,Rel8 is $(GROUP1) & ophi=2 & oplo=0; BitAddr & sfrbit & BitByteAddr; Rel8 { if (BitAddr == 1:1) goto Rel8; }
|
|
:JBC BitAddr,Rel8 is $(GROUP1) & ophi=1 & oplo=0; BitAddr & sfrbit & BitByteAddr; Rel8 { if (BitAddr == 0:1) goto inst_next; BitAddr = 0; goto Rel8; }
|
|
@elif BIT_OPS == "PCODEOPS"
|
|
:JB BitAddr,Rel8 is $(GROUP1) & ophi=2 & oplo=0; BitAddr & sfrbit & BitByteAddr; Rel8 { if (get(BitAddr, BitByteAddr)==1:1) goto Rel8; }
|
|
:JBC BitAddr,Rel8 is $(GROUP1) & ophi=1 & oplo=0; BitAddr & sfrbit & BitByteAddr; Rel8 { tmp:1 = get(BitAddr, BitByteAddr); if (tmp==0) goto inst_next; BitByteAddr = clr(BitAddr, BitByteAddr); goto Rel8; }
|
|
@elif BIT_OPS == "SHIFTS"
|
|
:JB BitAddr,Rel8 is $(GROUP1) & ophi=2 & oplo=0; BitAddr & sfrbit & BitByteAddr; Rel8 { if (((BitByteAddr>>sfrbit)&1) == 1:1) goto Rel8; }
|
|
:JBC BitAddr,Rel8 is $(GROUP1) & ophi=1 & oplo=0; BitAddr & sfrbit & BitByteAddr; Rel8 { tmp:1 = 1<<sfrbit; if ((BitByteAddr & tmp)==0) goto inst_next; BitByteAddr = BitByteAddr & ~tmp; goto Rel8; }
|
|
@endif
|
|
:JC Rel8 is $(GROUP1) & ophi=4 & oplo=0; Rel8 { if ($(CY) != 0) goto Rel8; }
|
|
:JMP ADPTR is $(GROUP1) & ophi=7 & oplo=3 & ADPTR { goto [ADPTR]; }
|
|
|
|
:JNB BitAddr,Rel8 is $(GROUP1) & ophi=3 & oplo=0; BitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr; Rel8 { if (((BitByteAddr>>sfrbit)&1)==0:1) goto Rel8; }
|
|
@if BIT_OPS == "BIT_ADDRS"
|
|
:JNB BitAddr,Rel8 is $(GROUP1) & ophi=3 & oplo=0; BitAddr & sfrbit & BitByteAddr; Rel8 { if (BitAddr == 0:1) goto Rel8; }
|
|
@elif BIT_OPS == "PCODEOPS"
|
|
:JNB BitAddr,Rel8 is $(GROUP1) & ophi=3 & oplo=0; BitAddr & sfrbit & BitByteAddr; Rel8 { if (get(BitAddr, BitByteAddr)==0:1) goto Rel8; }
|
|
@elif BIT_OPS == "SHIFTS"
|
|
:JNB BitAddr,Rel8 is $(GROUP1) & ophi=3 & oplo=0; BitAddr & sfrbit & BitByteAddr; Rel8 { if (((BitByteAddr>>sfrbit)&1)==0:1) goto Rel8; }
|
|
@endif
|
|
|
|
:JNC Rel8 is $(GROUP1) & ophi=5 & oplo=0; Rel8 { if ($(CY) == 0) goto Rel8; }
|
|
:JNZ Rel8 is $(GROUP1) & ophi=7 & oplo=0; Rel8 { if (ACC != 0) goto Rel8; }
|
|
:JZ Rel8 is $(GROUP1) & ophi=6 & oplo=0; Rel8 { if (ACC == 0) goto Rel8; }
|
|
|
|
@if defined(MCS80390)
|
|
:LCALL Addr24 is $(GROUP1) & ophi=1 & oplo=2; Addr24 { ret:$(PTRSIZE) = inst_next; push24(ret); call Addr24; }
|
|
:LJMP Addr24 is $(GROUP1) & ophi=0 & oplo=2; Addr24 { goto Addr24; }
|
|
@elif defined(MX51)
|
|
:LCALL Addr16 is $(GROUP1) & ophi=1 & oplo=2; Addr16 { ret:2 = inst_next; push16(ret); call Addr16; }
|
|
:LJMP Addr16 is $(GROUP1) & ophi=0 & oplo=2; Addr16 { goto Addr16; }
|
|
@else
|
|
:LCALL Addr16 is $(GROUP1) & ophi=1 & oplo=2; Addr16 { ret:$(PTRSIZE) = inst_next; push16(ret); call Addr16; }
|
|
:LJMP Addr16 is $(GROUP1) & ophi=0 & oplo=2; Addr16 { goto Addr16; }
|
|
@endif
|
|
|
|
:MOV Areg,rn is $(GROUP2) & ophi=14 & rnfill=1 & rn & Areg { ACC = rn; }
|
|
:MOV Areg,Direct is $(GROUP1) & ophi=14 & oplo=5 & Areg; Direct { ACC = Direct; }
|
|
:MOV Areg,Ri is $(GROUP2) & ophi=14 & Areg & rifill=3 & Ri { ACC = Ri; }
|
|
:MOV Areg,Data is $(GROUP1) & ophi=7 & oplo=4 & Areg; Data { ACC = Data; }
|
|
:MOV rn,Areg is $(GROUP2) & ophi=15 & rnfill=1 & rn & Areg { rn = ACC; }
|
|
:MOV rn,Direct is $(GROUP2) & ophi=10 & rnfill=1 & rn; Direct { rn = Direct; }
|
|
:MOV rn,Data is $(GROUP2) & ophi=7 & rnfill=1 & rn; Data { rn = Data; }
|
|
:MOV Direct,Areg is $(GROUP1) & ophi=15 & oplo=5 & Areg; Direct { Direct = ACC; }
|
|
:MOV Direct,rn is $(GROUP2) & ophi=8 & rnfill=1 & rn; Direct { Direct = rn; }
|
|
:MOV Direct2,Direct is $(GROUP1) & ophi=8 & oplo=5; Direct; Direct2 { Direct2 = Direct; }
|
|
:MOV Direct,Ri is $(GROUP2) & ophi=8 & rifill=3 & Ri; Direct { Direct = Ri; }
|
|
:MOV Direct,Data is $(GROUP1) & ophi=7 & oplo=5; Direct; Data { Direct = Data; }
|
|
:MOV Ri,Areg is $(GROUP2) & ophi=15 & rifill=3 & Ri & Areg { Ri = ACC; }
|
|
:MOV Ri,Direct is $(GROUP2) & ophi=10 & rifill=3 & Ri; Direct { Ri = Direct; }
|
|
:MOV Ri,Data is $(GROUP2) & ophi=7 & rifill=3 & Ri; Data { Ri = Data; }
|
|
@if defined(MCS80390)
|
|
:MOV DPTRreg,Data24 is $(GROUP1) & ophi=9 & oplo=0 & DPTRreg; Data24 { DPTR = Data24; }
|
|
@else
|
|
:MOV DPTRreg,Data16 is $(GROUP1) & ophi=9 & oplo=0 & DPTRreg; Data16 { DPTR = Data16; }
|
|
@endif
|
|
|
|
:MOV CY,BitAddr is $(GROUP1) & CY & ophi=10 & oplo=2; BitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr {$(CY)= (BitByteAddr>>sfrbit)&1; }
|
|
:MOV BitAddr,CY is $(GROUP1) & CY & ophi=9 & oplo=2; BitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr { BitByteAddr = BitByteAddr & (~(1<<sfrbit)); BitByteAddr = BitByteAddr | ($(CY)<<sfrbit); }
|
|
@if BIT_OPS == "BIT_ADDRS"
|
|
:MOV CY,BitAddr is $(GROUP1) & CY & ophi=10 & oplo=2; BitAddr & sfrbit & BitByteAddr {$(CY)= BitAddr; }
|
|
:MOV BitAddr,CY is $(GROUP1) & CY & ophi=9 & oplo=2; BitAddr & sfrbit & BitByteAddr { BitAddr = $(CY); }
|
|
@elif BIT_OPS == "PCODEOPS"
|
|
:MOV CY,BitAddr is $(GROUP1) & CY & ophi=10 & oplo=2; BitAddr & sfrbit & BitByteAddr {$(CY) = get(BitAddr, BitByteAddr); }
|
|
:MOV BitAddr,CY is $(GROUP1) & CY & ophi=9 & oplo=2; BitAddr & sfrbit & BitByteAddr { BitByteAddr = set_bit_value(BitAddr, $(CY), BitByteAddr); }
|
|
@elif BIT_OPS == "SHIFTS"
|
|
:MOV CY,BitAddr is $(GROUP1) & CY & ophi=10 & oplo=2; BitAddr & sfrbit & BitByteAddr{$(CY)= (BitByteAddr>>sfrbit)&1; }
|
|
:MOV BitAddr,CY is $(GROUP1) & CY & ophi=9 & oplo=2; BitAddr & sfrbit & BitByteAddr { BitByteAddr = BitByteAddr & (~(1<<sfrbit)); BitByteAddr = BitByteAddr | ($(CY)<<sfrbit); }
|
|
@endif
|
|
|
|
:MOVC Areg,ADPTR is $(GROUP1) & ophi=9 & oplo=3 & ADPTR & Areg { ACC = *:1 ADPTR; }
|
|
:MOVC Areg,APC is $(GROUP1) & ophi=8 & oplo=3 & APC & Areg { ACC = *:1 APC; }
|
|
|
|
:MOVX Areg,RiX is $(GROUP2) & ophi=14 & rifill=1 & RiX & Areg { ACC = RiX; }
|
|
:MOVX Areg,ATDPTR is $(GROUP1) & ophi=14 & oplo=0 & Areg & ATDPTR { ACC = ATDPTR; }
|
|
:MOVX RiX,Areg is $(GROUP2) & ophi=15 & rifill=1 & RiX & Areg { RiX = ACC; }
|
|
:MOVX ATDPTR,Areg is $(GROUP1) & ophi=15 & oplo=0 & Areg & ATDPTR { ATDPTR = ACC; }
|
|
|
|
:MUL ABreg is $(GROUP1) & ophi=10 & oplo=4 & ABreg { PSW = PSW & 0x7b; tmp:2 = zext(ACC) * zext(B); ACC = tmp(0); B = tmp(1); PSW = PSW | ((B!=0)<<2); }
|
|
#:MUL Areg,Breg is $(GROUP1) & ophi=10 & oplo=4 & Areg & Breg { PSW = PSW & 0x7b; tmp:2 = zext(ACC) * zext(B); ACC = tmp(0); B = tmp(1); PSW = PSW | ((B!=0)<<2); }
|
|
|
|
:NOP is $(GROUP1) & ophi=0 & oplo=0 { nop(); }
|
|
|
|
:ORL Areg,rn is $(GROUP2) & ophi=4 & rnfill=1 & rn & Areg { ACC = ACC | rn; }
|
|
:ORL Areg,Direct is $(GROUP1) & ophi=4 & oplo=5 & Areg; Direct { ACC = ACC | Direct; }
|
|
:ORL Areg,Ri is $(GROUP2) & ophi=4 & Areg & rifill=3 & Ri { ACC = ACC | Ri; }
|
|
:ORL Areg,Data is $(GROUP1) & ophi=4 & oplo=4 & Areg; Data { ACC = ACC | Data; }
|
|
:ORL Direct,Areg is $(GROUP1) & ophi=4 & oplo=2 & Areg; Direct { Direct = Direct | ACC; }
|
|
:ORL Direct,Data is $(GROUP1) & ophi=4 & oplo=3 & Areg; Direct; Data { Direct = Direct | Data; }
|
|
|
|
:ORL CY,BitAddr is $(GROUP1) & CY & ophi=7 & oplo=2; BitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr {$(CY)=$(CY)| ((BitByteAddr>>sfrbit)&1); }
|
|
:ORL CY,BitAddr2 is $(GROUP1) & CY & ophi=10 & oplo=0; BitAddr2 & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr {$(CY)=$(CY)| (((BitByteAddr>>sfrbit)&1)^1); }
|
|
@if BIT_OPS == "BIT_ADDRS"
|
|
:ORL CY,BitAddr is $(GROUP1) & CY & ophi=7 & oplo=2; BitAddr & sfrbit & BitByteAddr {$(CY)=$(CY)| BitAddr; }
|
|
:ORL CY,BitAddr2 is $(GROUP1) & CY & ophi=10 & oplo=0; BitAddr2 & sfrbit & BitByteAddr {$(CY)=$(CY)| (BitAddr2^1); }
|
|
@elif BIT_OPS == "PCODEOPS"
|
|
:ORL CY,BitAddr is $(GROUP1) & CY & ophi=7 & oplo=2; BitAddr & sfrbit & BitByteAddr {$(CY)=$(CY)| get(BitAddr, BitByteAddr); }
|
|
:ORL CY,BitAddr2 is $(GROUP1) & CY & ophi=10 & oplo=0; BitAddr2 & sfrbit & BitByteAddr {$(CY)=$(CY)| (get(BitAddr2, BitByteAddr)^1); }
|
|
@elif BIT_OPS == "SHIFTS"
|
|
:ORL CY,BitAddr is $(GROUP1) & CY & ophi=7 & oplo=2; BitAddr & sfrbit & BitByteAddr {$(CY)=$(CY)| ((BitByteAddr>>sfrbit)&1); }
|
|
:ORL CY,BitAddr2 is $(GROUP1) & CY & ophi=10 & oplo=0; BitAddr2 & sfrbit & BitByteAddr {$(CY)=$(CY)| (((BitByteAddr>>sfrbit)&1)^1); }
|
|
@endif
|
|
|
|
:POP Direct is $(GROUP1) & ophi=13 & oplo=0; Direct { pop8(Direct); }
|
|
|
|
:PUSH Direct is $(GROUP1) & ophi=12 & oplo=0; Direct { push8(Direct); }
|
|
|
|
:RET is $(GROUP1) & ophi=2 & oplo=2 {
|
|
@if defined(MCS251) || defined(MX51)
|
|
pc:2 = 0; pop16(pc); pc3:3 = (inst_next & 0xff0000) + zext(pc); return[pc3];
|
|
@elif defined(MCS51)
|
|
pc:2 = 0; pop16(pc); return[pc];
|
|
@elif defined(MCS80390)
|
|
pc:3 = 0; pop24(pc); return[pc];
|
|
@endif
|
|
}
|
|
|
|
:RETI is $(GROUP1) & ophi=3 & oplo=2 {
|
|
@if defined(MCS251) || defined(MX51)
|
|
pc:2 = 0; pop16(pc); pc3:3 = (inst_next & 0xff0000) + zext(pc); return[pc3];
|
|
@elif defined(MCS51)
|
|
pc:2 = 0; pop16(pc); return[pc];
|
|
@elif defined(MCS80390)
|
|
pc:3 = 0; pop24(pc); return[pc];
|
|
@endif
|
|
}
|
|
|
|
:RL Areg is $(GROUP1) & ophi=2 & oplo=3 & Areg { ACC = (ACC<<1) | (ACC>>7); }
|
|
:RLC Areg is $(GROUP1) & ophi=3 & oplo=3 & Areg { tmp : 1 = (ACC&0x80)>>7; ACC = (ACC<<1) | $(CY);$(CY)= tmp; }
|
|
:RR Areg is $(GROUP1) & ophi=0 & oplo=3 & Areg { ACC = (ACC>>1) | (ACC<<7); }
|
|
:RRC Areg is $(GROUP1) & ophi=1 & oplo=3 & Areg { tmp : 1 = ACC&1; ACC = (ACC>>1) | ($(CY)<<7);$(CY)= tmp; }
|
|
|
|
:SETB CY is $(GROUP1) & CY & ophi=13 & oplo=3 { $(CY)=1; }
|
|
|
|
:SETB BitAddr is $(GROUP1) & ophi=13 & oplo=2; BitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr { BitByteAddr = BitByteAddr | (1<<sfrbit); }
|
|
@if BIT_OPS == "BIT_ADDRS"
|
|
:SETB BitAddr is $(GROUP1) & ophi=13 & oplo=2; BitAddr & sfrbit & BitByteAddr { BitAddr = 1; }
|
|
@elif BIT_OPS == "PCODEOPS"
|
|
:SETB BitAddr is $(GROUP1) & ophi=13 & oplo=2; BitAddr & sfrbit & BitByteAddr { BitByteAddr = set(BitAddr, BitByteAddr); }
|
|
@elif BIT_OPS == "SHIFTS"
|
|
:SETB BitAddr is $(GROUP1) & ophi=13 & oplo=2; BitAddr & sfrbit & BitByteAddr { BitByteAddr = BitByteAddr | (1<<sfrbit); }
|
|
@endif
|
|
|
|
:SJMP Rel8 is $(GROUP1) & ophi=8 & oplo=0; Rel8 { goto Rel8; }
|
|
|
|
:SUBB Areg,rn is $(GROUP2) & ophi=9 & rnfill=1 & rn & Areg { tmp : 1 = rn+$(CY); subflags(ACC,tmp); ACC = ACC - tmp; }
|
|
:SUBB Areg,Direct is $(GROUP1) & ophi=9 & oplo=5 & Areg; Direct { tmp:1 = Direct+$(CY); subflags(ACC,tmp); ACC = ACC - tmp; }
|
|
:SUBB Areg,Ri is $(GROUP2) & ophi=9 & Areg & rifill=3 & Ri { local tmp = Ri+$(CY); subflags(ACC,tmp); ACC = ACC - tmp; }
|
|
:SUBB Areg,Data is $(GROUP1) & ophi=9 & oplo=4 & Areg; Data { tmp:1 = Data+$(CY); subflags(ACC,tmp); ACC = ACC - tmp; }
|
|
|
|
:SWAP Areg is $(GROUP1) & ophi=12 & oplo=4 & Areg { ACC = (ACC>>4) | (ACC<<4); }
|
|
|
|
:XCH Areg,rn is $(GROUP2) & ophi=12 & rnfill=1 & rn & Areg { tmp : 1 = ACC; ACC = rn; rn = tmp; }
|
|
:XCH Areg,Direct is $(GROUP1) & ophi=12 & oplo=5 & Areg; Direct { tmp : 1 = ACC; ACC = Direct; Direct = tmp; }
|
|
:XCH Areg,Ri is $(GROUP2) & ophi=12 & rifill=3 & Ri & Areg { tmp : 1 = ACC; ACC = Ri; Ri = tmp; }
|
|
|
|
# TODO: This instruction appears to be in both GROUP2 & GROUP3 (always available)
|
|
:XCHD Areg,Ri is ophi=13 & Areg & rifill=3 & Ri { tmp : 1 = ACC & 0xf; ACC = (ACC&0xf0) | (Ri&0xf); Ri = (Ri&0xf0) | tmp; }
|
|
|
|
:XRL Areg,rn is $(GROUP2) & ophi=6 & rnfill=1 & rn & Areg { ACC = ACC ^ rn; }
|
|
:XRL Areg,Direct is $(GROUP1) & ophi=6 & oplo=5 & Areg; Direct { ACC = ACC ^ Direct; }
|
|
:XRL Areg,Ri is $(GROUP2) & ophi=6 & rifill=3 & Ri & Areg { ACC = ACC ^ Ri; }
|
|
:XRL Areg,Data is $(GROUP1) & ophi=6 & oplo=4 & Areg; Data { ACC = ACC ^ Data; }
|
|
:XRL Direct,Areg is $(GROUP1) & ophi=6 & oplo=2 & Areg; Direct { Direct = Direct ^ ACC; }
|
|
:XRL Direct,Data is $(GROUP1) & ophi=6 & oplo=3; Direct; Data { Direct = Direct ^ Data; }
|
|
|