333 lines
16 KiB
Plaintext
333 lines
16 KiB
Plaintext
# Extended mx51 instructions live here, so as to avoid further
|
|
# complicating the main 8051 file.
|
|
|
|
# All have 0xa5 as prefix, so subtract one
|
|
define token TwoByteOp (8)
|
|
b2op = (0,7)
|
|
;
|
|
define token ThreeByteOp (16)
|
|
b3op = (8,15)
|
|
;
|
|
define token FourByteOp (24)
|
|
b4op = (16,23)
|
|
;
|
|
|
|
define token EcallDispTok (24)
|
|
imm24 = (0,23)
|
|
;
|
|
|
|
####################
|
|
|
|
# Note that PRi is used in little endian format, as R3 is the MSB
|
|
attach variables PRi_revend [ R1R2R3 R5R6R7 ];
|
|
@define ENDIANSWAPFUNC ""
|
|
@if defined(ENDIANSWAPFUNC)
|
|
define pcodeop endian_swap;
|
|
PRi: PRi_revend is PRi_revend { tmp:3 = endian_swap(PRi_revend); export tmp; }
|
|
@else
|
|
PRi: PRi_revend is PRi_sel=0 & PRi_revend { tmp:3 = (zext(R3) << 16) | (zext(R2) << 8) | zext(R1); export tmp; }
|
|
PRi: PRi_revend is PRi_sel=1 & PRi_revend { tmp:3 = (zext(R7) << 16) | (zext(R6) << 8) | zext(R5); export tmp; }
|
|
@endif
|
|
####################
|
|
|
|
@ifdef OMIT_RETADDR
|
|
macro push24(val) { val = val; }
|
|
macro pop24(val) { val = val; }
|
|
|
|
@else
|
|
# stack grows up.
|
|
macro push24(val) {
|
|
ptr:3 = zext(SP) + 1 + $(STACKBASE);
|
|
*[RAM]:3 ptr = val;
|
|
SP = SP + 2;
|
|
}
|
|
macro pop24(val) {
|
|
ptr:3 = zext(SP - 2) + $(STACKBASE);
|
|
val = *[RAM]:3 ptr;
|
|
SP = SP - 3;
|
|
}
|
|
@endif
|
|
|
|
####################
|
|
|
|
eptrReg: EPTR is EPTR { export EPTR; }
|
|
APlusEptr: "@"Areg"+"eptrReg is Areg & eptrReg { tmp:3 = EPTR + zext(ACC); export tmp; }
|
|
ecallImmAddr: imm24 is imm24 { export *:1 imm24; }
|
|
add_with_pr_const: emov_delta is emov_delta { tmp:1 = emov_delta; export tmp; }
|
|
add_with_pr_const: "4" is emov_delta = 0 { tmp:1 = 4; export tmp; }
|
|
|
|
EDirect: mainreg is bank=0 & mainreg { tmp:3 = mainreg + 0x7f0000; export *[RAM]:1 tmp; }
|
|
EDirect: direct is bank=1 & direct { export *[ESFR]:1 direct; }
|
|
EDirect: EPL is bank=1 & direct=0xfc & EPL { export EPL; }
|
|
EDirect: EPM is bank=1 & direct=0xfd & EPM { export EPM; }
|
|
EDirect: EPH is bank=1 & direct=0xfe & EPH { export EPH; }
|
|
|
|
EDirect2: mainreg2 is bank2=0 & mainreg2 { tmp:3 = mainreg2 + 0x7f0000; export *[RAM]:1 tmp; }
|
|
EDirect2: direct2 is bank2=1 & direct2 { export *[ESFR]:1 direct2; }
|
|
EDirect2: EPL is bank2=1 & direct2=0xfc & EPL { export EPL; }
|
|
EDirect2: EPM is bank2=1 & direct2=0xfd & EPM { export EPM; }
|
|
EDirect2: EPH is bank2=1 & direct2=0xfe & EPH { export EPH; }
|
|
|
|
# Continuing with pattern via copying from stock 8051 sleighspec.
|
|
# Note that there is a known bug with the Bit addressing of the SFR.
|
|
EBitAddr: bitaddr is bitbank=1 & sfrbyte & sfrbit [ bitaddr =(sfrbyte << 3)+sfrbit; ] { export *[EBITS]:1 bitaddr; }
|
|
EBitAddr: bitaddr is bitbank=0 & lowbyte & sfrbit [ bitaddr =(lowbyte << 3)+sfrbit; ] { export *[EBITS]:1 bitaddr; }
|
|
EBitAddr2: "/"bitaddr is bitbank=1 & sfrbyte & sfrbit [ bitaddr =(sfrbyte << 3)+sfrbit; ] { export *[EBITS]:1 bitaddr; }
|
|
EBitAddr2: "/"bitaddr is bitbank=0 & lowbyte & sfrbit [ bitaddr =(lowbyte << 3)+sfrbit; ] { export *[EBITS]:1 bitaddr; }
|
|
|
|
EBitByteAddr: byteaddr is bitbank=1 & sfrbyte & sfrbit [ byteaddr =(sfrbyte << 3); ] { export *[ESFR]:1 byteaddr; }
|
|
EBitByteAddr: byteaddr is bitbank=0 & lowbyte & sfrbit [ byteaddr = lowbyte + 0x20; ] { tmp:3 = byteaddr + 0x7f0000; export *[RAM]:1 tmp; }
|
|
|
|
|
|
####################
|
|
|
|
:inc EDirect is opfull=0xa5; ophi=0 & oplo=5; EDirect {
|
|
EDirect = EDirect + 1;
|
|
}
|
|
:dec EDirect is opfull=0xa5; opfull=0x15; EDirect {
|
|
EDirect = EDirect - 1;
|
|
}
|
|
:add Areg,EDirect is opfull=0xa5; opfull=0x25 & Areg; EDirect {
|
|
addflags(ACC,EDirect); ACC = ACC + EDirect; resultflags(ACC);
|
|
}
|
|
:addc Areg,EDirect is opfull=0xa5; opfull=0x35 & Areg; EDirect {
|
|
tmp:1 =$(CY)+ EDirect; addflags(ACC,tmp); ACC = ACC + tmp; resultflags(ACC);
|
|
}
|
|
:orl Areg,EDirect is opfull=0xa5; opfull=0x45 & Areg; EDirect {
|
|
ACC = ACC | EDirect;
|
|
}
|
|
:anl Areg,EDirect is opfull=0xa5; opfull=0x55 & Areg; EDirect {
|
|
ACC = ACC & EDirect; resultflags(ACC);
|
|
}
|
|
:xrl Areg,EDirect is opfull=0xa5; opfull=0x65 & Areg; EDirect {
|
|
ACC = ACC ^ EDirect;
|
|
}
|
|
:subb Areg,EDirect is opfull=0xa5; opfull=0x95 & Areg; EDirect {
|
|
tmp:1 = EDirect+$(CY); subflags(ACC,tmp); ACC = ACC - tmp;
|
|
}
|
|
:xch Areg,EDirect is opfull=0xa5; opfull=0xc5 & Areg; EDirect {
|
|
tmp:1 = ACC; ACC = EDirect; EDirect = tmp;
|
|
}
|
|
:mov Areg,EDirect is opfull=0xa5; opfull=0xe5 & Areg; EDirect {
|
|
ACC = EDirect;
|
|
}
|
|
:mov EDirect,Areg is opfull=0xa5; opfull=0xf5 & Areg; EDirect {
|
|
EDirect = ACC;
|
|
}
|
|
:mov EDirect,rn is opfull=0xa5; ophi=0x8 & rnfill=1 & rn; EDirect {
|
|
EDirect = rn;
|
|
}
|
|
:mov rn,EDirect is opfull=0xa5; ophi=0xa & rnfill=1 & rn; EDirect {
|
|
rn = EDirect;
|
|
}
|
|
:mov EDirect2,EDirect is opfull=0xa5; ophi=8 & oplo=5; EDirect; EDirect2 {
|
|
EDirect2 = EDirect;
|
|
}
|
|
:mov EDirect,Data is opfull=0xa5; ophi=7 & oplo=5; EDirect; Data {
|
|
EDirect = Data;
|
|
}
|
|
:mov EDirect,Ri is opfull=0xa5; ophi=8 & rifill=3 & Ri; EDirect {
|
|
EDirect = Ri;
|
|
}
|
|
:mov Ri,EDirect is opfull=0xa5; ophi=10 & rifill=3 & Ri; EDirect {
|
|
Ri = EDirect;
|
|
}
|
|
:orl EDirect,Areg is opfull=0xa5; ophi=4 & oplo=2 & Areg; EDirect {
|
|
EDirect = EDirect | ACC;
|
|
}
|
|
:anl EDirect,Areg is opfull=0xa5; ophi=5 & oplo=2 & Areg; EDirect {
|
|
tmp:1 = EDirect & ACC; EDirect = tmp; resultflags(tmp);
|
|
}
|
|
:xrl EDirect,Areg is opfull=0xa5; ophi=6 & oplo=2 & Areg; EDirect {
|
|
EDirect = EDirect ^ ACC;
|
|
}
|
|
:xrl EDirect,Data is opfull=0xa5; ophi=6 & oplo=3; EDirect; Data {
|
|
EDirect = EDirect ^ Data;
|
|
}
|
|
:anl EDirect,Data is opfull=0xa5; ophi=5 & oplo=3; EDirect; Data {
|
|
tmp:1 = EDirect & Data; EDirect = tmp; resultflags(tmp);
|
|
}
|
|
:orl EDirect,Data is opfull=0xa5; ophi=4 & oplo=3 & Areg; EDirect; Data {
|
|
EDirect = EDirect | Data;
|
|
}
|
|
:push EDirect is opfull=0xa5; opfull=0xc0; EDirect {
|
|
push8(EDirect);
|
|
}
|
|
:pop EDirect is opfull=0xa5; opfull=0xd0; EDirect {
|
|
pop8(EDirect);
|
|
}
|
|
:cjne Areg,EDirect,Rel8 is opfull=0xa5; ophi=11 & oplo=5 & Areg; EDirect; Rel8 {
|
|
compflags(ACC,EDirect); if (ACC!=EDirect) goto Rel8;
|
|
}
|
|
:djnz EDirect,Rel8 is opfull=0xa5; ophi=13 & oplo=5; EDirect; Rel8 {
|
|
EDirect = EDirect - 1;
|
|
if (EDirect!=0) goto Rel8;
|
|
}
|
|
|
|
|
|
# EPTR operations
|
|
:ejmp ecallImmAddr is opfull=0xa5; opfull=0x02; ecallImmAddr {
|
|
goto ecallImmAddr;
|
|
}
|
|
:ecall ecallImmAddr is opfull=0xa5; opfull=0x12; ecallImmAddr {
|
|
ret:3 = inst_next; push24(ret); call ecallImmAddr;
|
|
}
|
|
:mov eptrReg,ecallImmAddr is opfull=0xa5; opfull=0x90; ecallImmAddr & eptrReg & imm24 {
|
|
EPTR = imm24;
|
|
}
|
|
:eret is opfull=0xa5; opfull=0x22 {
|
|
pc:3 = 0; pop24(pc); return[pc];
|
|
}
|
|
:jmp APlusEptr is opfull=0xa5; opfull=0x73 & APlusEptr {
|
|
# this is correct, but causes disassembler problems
|
|
# goto APlusEptr;
|
|
# added additional indirection to stop disassembler problems.
|
|
goto [APlusEptr];
|
|
}
|
|
:movx Areg",@"eptrReg is opfull=0xa5; opfull=0xe0 & Areg & eptrReg {
|
|
ACC = *:1 EPTR;
|
|
}
|
|
:movx "@"eptrReg,Areg is opfull=0xa5; opfull=0xf0 & Areg & eptrReg {
|
|
*:1 EPTR = ACC;
|
|
}
|
|
:movc Areg,APlusEptr is opfull=0xa5; opfull=0x93 & Areg & APlusEptr {
|
|
ACC = *:1 APlusEptr;
|
|
}
|
|
:inc EPTR is opfull=0xa5; opfull=0xa3 & EPTR {
|
|
EPTR = EPTR + 1;
|
|
}
|
|
|
|
# PRi operations
|
|
:emov Areg",@"PRi"+"emov_delta is opfull=0xa5; ophi=4 & PRi & emov_delta & Areg {
|
|
tmp:3 = zext(PRi) + emov_delta;
|
|
ACC = *:1 tmp;
|
|
}
|
|
:emov "@"PRi"+"emov_delta,Areg is opfull=0xa5; ophi=5 & PRi & emov_delta & Areg {
|
|
tmp:3 = PRi + emov_delta;
|
|
*:1 tmp = ACC;
|
|
}
|
|
:add PRi_revend,add_with_pr_const is opfull=0xa5; ophi=6 & PRi_revend & PRi & add_with_pr_const {
|
|
x:3 = zext(add_with_pr_const);
|
|
tmp:3 = PRi + x;
|
|
@if defined(ENDIANSWAPFUNC)
|
|
y:3 = endian_swap(tmp);
|
|
@else
|
|
y:3 = (tmp << 16) | (tmp & 0x00ff00) | zext(tmp >> 16);
|
|
@endif
|
|
PRi_revend = y;
|
|
}
|
|
|
|
# bit operations
|
|
:anl CY,EBitAddr is opfull=0xa5; CY & ophi=8 & oplo=2; EBitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr {tmp:1 = EBitByteAddr; $(CY)=$(CY)& ((tmp>>sfrbit)&1); resultflags(tmp); }
|
|
:anl CY,EBitAddr2 is opfull=0xa5; CY & ophi=11 & oplo=0; EBitAddr2 & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr {tmp:1 = EBitByteAddr; $(CY)=$(CY)& (~((tmp>>sfrbit)&1)); }
|
|
@if BIT_OPS == "BIT_ADDRS"
|
|
:anl CY,EBitAddr is opfull=0xa5; CY & ophi=8 & oplo=2; EBitAddr & sfrbit & EBitByteAddr {$(CY)=$(CY)& EBitAddr; }
|
|
:anl CY,EBitAddr2 is opfull=0xa5; CY & ophi=11 & oplo=0; EBitAddr2 & sfrbit & EBitByteAddr {$(CY)=$(CY)& ~EBitAddr2; }
|
|
@elif BIT_OPS == "PCODEOPS"
|
|
:anl CY,EBitAddr is opfull=0xa5; CY & ophi=8 & oplo=2; EBitAddr & sfrbit & EBitByteAddr {$(CY)=$(CY)& get(EBitAddr, EBitByteAddr); }
|
|
:anl CY,EBitAddr2 is opfull=0xa5; CY & ophi=11 & oplo=0; EBitAddr2 & sfrbit & EBitByteAddr {$(CY)=$(CY)& (get(EBitAddr2, EBitByteAddr)^1); }
|
|
@elif BIT_OPS == "SHIFTS"
|
|
:anl CY,EBitAddr is opfull=0xa5; CY & ophi=8 & oplo=2; EBitAddr & sfrbit & EBitByteAddr {$(CY)=$(CY)& ((EBitByteAddr>>sfrbit)&1); }
|
|
:anl CY,EBitAddr2 is opfull=0xa5; CY & ophi=11 & oplo=0; EBitAddr2 & sfrbit & EBitByteAddr {$(CY)=$(CY)& (~((EBitByteAddr>>sfrbit)&1)); }
|
|
@endif
|
|
|
|
:clr EBitAddr is opfull=0xa5; ophi=12 & oplo=2; EBitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr { tmp:1 = ~(1<<sfrbit); EBitByteAddr = EBitByteAddr & tmp; }
|
|
@if BIT_OPS == "BIT_ADDRS"
|
|
:clr EBitAddr is opfull=0xa5; ophi=12 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { EBitAddr = 0; }
|
|
@elif BIT_OPS == "PCODEOPS"
|
|
:clr EBitAddr is opfull=0xa5; ophi=12 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { EBitByteAddr = clr(EBitAddr, EBitByteAddr); }
|
|
#:CLR PortBit is opfull=0xa5; ophi=12 & oplo=2; PortBit & sfrbit & EBitByteAddr { outp(PortBit, 0:1, EBitByteAddr); }
|
|
@elif BIT_OPS == "SHIFTS"
|
|
:clr EBitAddr is opfull=0xa5; ophi=12 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { tmp:1 = ~(1<<sfrbit); EBitByteAddr = EBitByteAddr & tmp; }
|
|
@endif
|
|
|
|
:cpl EBitAddr is opfull=0xa5; ophi=11 & oplo=2; EBitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr { tmp:1 = (1<<sfrbit); EBitByteAddr = EBitByteAddr ^ tmp; }
|
|
@if BIT_OPS == "BIT_ADDRS"
|
|
:cpl EBitAddr is opfull=0xa5; ophi=11 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { EBitAddr = EBitAddr ^ 1; }
|
|
@elif BIT_OPS == "PCODEOPS"
|
|
:cpl EBitAddr is opfull=0xa5; ophi=11 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { tmp:1 = get(EBitAddr, EBitByteAddr) ^ 1; EBitByteAddr = set_bit_value(EBitAddr, tmp, EBitByteAddr); }
|
|
@elif BIT_OPS == "SHIFTS"
|
|
:cpl EBitAddr is opfull=0xa5; ophi=11 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { tmp:1 = (1<<sfrbit); EBitByteAddr = EBitByteAddr ^ tmp; }
|
|
@endif
|
|
|
|
:jb EBitAddr,Rel8 is opfull=0xa5; ophi=2 & oplo=0; EBitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr; Rel8 { if (((EBitByteAddr>>sfrbit)&1) == 1:1) goto Rel8; }
|
|
:jbc EBitAddr,Rel8 is opfull=0xa5; ophi=1 & oplo=0; EBitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr; Rel8 { tmp:1 = 1<<sfrbit; if ((EBitByteAddr & tmp)==0) goto inst_next; EBitByteAddr = EBitByteAddr & ~tmp; goto Rel8; }
|
|
@if BIT_OPS == "BIT_ADDRS"
|
|
:jb EBitAddr,Rel8 is opfull=0xa5; ophi=2 & oplo=0; EBitAddr & sfrbit & EBitByteAddr; Rel8 { if (EBitAddr == 1:1) goto Rel8; }
|
|
:jbc EBitAddr,Rel8 is opfull=0xa5; ophi=1 & oplo=0; EBitAddr & sfrbit & EBitByteAddr; Rel8 { if (EBitAddr == 0:1) goto inst_next; EBitAddr = 0; goto Rel8; }
|
|
@elif BIT_OPS == "PCODEOPS"
|
|
:jb EBitAddr,Rel8 is opfull=0xa5; ophi=2 & oplo=0; EBitAddr & sfrbit & EBitByteAddr; Rel8 { if (get(EBitAddr, EBitByteAddr)==1:1) goto Rel8; }
|
|
:jbc EBitAddr,Rel8 is opfull=0xa5; ophi=1 & oplo=0; EBitAddr & sfrbit & EBitByteAddr; Rel8 { tmp:1 = get(EBitAddr, EBitByteAddr); if (tmp==0) goto inst_next; EBitByteAddr = clr(EBitAddr, EBitByteAddr); goto Rel8; }
|
|
@elif BIT_OPS == "SHIFTS"
|
|
:jb EBitAddr,Rel8 is opfull=0xa5; ophi=2 & oplo=0; EBitAddr & sfrbit & EBitByteAddr; Rel8 { if (((EBitByteAddr>>sfrbit)&1) == 1:1) goto Rel8; }
|
|
:jbc EBitAddr,Rel8 is opfull=0xa5; ophi=1 & oplo=0; EBitAddr & sfrbit & EBitByteAddr; Rel8 { tmp:1 = 1<<sfrbit; if ((EBitByteAddr & tmp)==0) goto inst_next; EBitByteAddr = EBitByteAddr & ~tmp; goto Rel8; }
|
|
@endif
|
|
|
|
:jnb EBitAddr,Rel8 is opfull=0xa5; ophi=3 & oplo=0; EBitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr; Rel8 { if (((EBitByteAddr>>sfrbit)&1)==0:1) goto Rel8; }
|
|
@if BIT_OPS == "BIT_ADDRS"
|
|
:jnb EBitAddr,Rel8 is opfull=0xa5; ophi=3 & oplo=0; EBitAddr & sfrbit & EBitByteAddr; Rel8 { if (EBitAddr == 0:1) goto Rel8; }
|
|
@elif BIT_OPS == "PCODEOPS"
|
|
:jnb EBitAddr,Rel8 is opfull=0xa5; ophi=3 & oplo=0; EBitAddr & sfrbit & EBitByteAddr; Rel8 { if (get(EBitAddr, EBitByteAddr)==0:1) goto Rel8; }
|
|
@elif BIT_OPS == "SHIFTS"
|
|
:jnb EBitAddr,Rel8 is opfull=0xa5; ophi=3 & oplo=0; EBitAddr & sfrbit & EBitByteAddr; Rel8 { if (((EBitByteAddr>>sfrbit)&1)==0:1) goto Rel8; }
|
|
@endif
|
|
|
|
:mov CY,EBitAddr is opfull=0xa5; CY & ophi=10 & oplo=2; EBitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr {$(CY)= (EBitByteAddr>>sfrbit)&1; }
|
|
:mov EBitAddr,CY is opfull=0xa5; CY & ophi=9 & oplo=2; EBitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr { EBitByteAddr = EBitByteAddr & (~(1<<sfrbit)); EBitByteAddr = EBitByteAddr | ($(CY)<<sfrbit); }
|
|
@if BIT_OPS == "BIT_ADDRS"
|
|
:mov CY,EBitAddr is opfull=0xa5; CY & ophi=10 & oplo=2; EBitAddr & sfrbit & EBitByteAddr {$(CY)= EBitAddr; }
|
|
:mov EBitAddr,CY is opfull=0xa5; CY & ophi=9 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { EBitAddr = $(CY); }
|
|
@elif BIT_OPS == "PCODEOPS"
|
|
:mov CY,EBitAddr is opfull=0xa5; CY & ophi=10 & oplo=2; EBitAddr & sfrbit & EBitByteAddr {$(CY) = get(EBitAddr, EBitByteAddr); }
|
|
:mov EBitAddr,CY is opfull=0xa5; CY & ophi=9 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { EBitByteAddr = set_bit_value(EBitAddr, $(CY), EBitByteAddr); }
|
|
@elif BIT_OPS == "SHIFTS"
|
|
:mov CY,EBitAddr is opfull=0xa5; CY & ophi=10 & oplo=2; EBitAddr & sfrbit & EBitByteAddr{$(CY)= (EBitByteAddr>>sfrbit)&1; }
|
|
:mov EBitAddr,CY is opfull=0xa5; CY & ophi=9 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { EBitByteAddr = EBitByteAddr & (~(1<<sfrbit)); EBitByteAddr = EBitByteAddr | ($(CY)<<sfrbit); }
|
|
@endif
|
|
|
|
:orl CY,EBitAddr is opfull=0xa5; CY & ophi=7 & oplo=2; EBitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr {$(CY)=$(CY)| ((EBitByteAddr>>sfrbit)&1); }
|
|
:orl CY,EBitAddr2 is opfull=0xa5; CY & ophi=10 & oplo=0; EBitAddr2 & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr {$(CY)=$(CY)| (((EBitByteAddr>>sfrbit)&1)^1); }
|
|
@if BIT_OPS == "BIT_ADDRS"
|
|
:orl CY,EBitAddr is opfull=0xa5; CY & ophi=7 & oplo=2; EBitAddr & sfrbit & EBitByteAddr {$(CY)=$(CY)| EBitAddr; }
|
|
:orl CY,EBitAddr2 is opfull=0xa5; CY & ophi=10 & oplo=0; EBitAddr2 & sfrbit & EBitByteAddr {$(CY)=$(CY)| (EBitAddr2^1); }
|
|
@elif BIT_OPS == "PCODEOPS"
|
|
:orl CY,EBitAddr is opfull=0xa5; CY & ophi=7 & oplo=2; EBitAddr & sfrbit & EBitByteAddr {$(CY)=$(CY)| get(EBitAddr, EBitByteAddr); }
|
|
:orl CY,EBitAddr2 is opfull=0xa5; CY & ophi=10 & oplo=0; EBitAddr2 & sfrbit & EBitByteAddr {$(CY)=$(CY)| (get(EBitAddr2, EBitByteAddr)^1); }
|
|
@elif BIT_OPS == "SHIFTS"
|
|
:orl CY,EBitAddr is opfull=0xa5; CY & ophi=7 & oplo=2; EBitAddr & sfrbit & EBitByteAddr {$(CY)=$(CY)| ((EBitByteAddr>>sfrbit)&1); }
|
|
:orl CY,EBitAddr2 is opfull=0xa5; CY & ophi=10 & oplo=0; EBitAddr2 & sfrbit & EBitByteAddr {$(CY)=$(CY)| (((EBitByteAddr>>sfrbit)&1)^1); }
|
|
@endif
|
|
|
|
:setb EBitAddr is opfull=0xa5; ophi=13 & oplo=2; EBitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr { EBitByteAddr = EBitByteAddr | (1<<sfrbit); }
|
|
@if BIT_OPS == "BIT_ADDRS"
|
|
:setb EBitAddr is opfull=0xa5; ophi=13 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { EBitAddr = 1; }
|
|
@elif BIT_OPS == "PCODEOPS"
|
|
:setb EBitAddr is opfull=0xa5; ophi=13 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { EBitByteAddr = set(EBitAddr, EBitByteAddr); }
|
|
@elif BIT_OPS == "SHIFTS"
|
|
:setb EBitAddr is opfull=0xa5; ophi=13 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { EBitByteAddr = EBitByteAddr | (1<<sfrbit); }
|
|
@endif
|
|
|
|
########################################################################
|
|
@if defined(INS_FUSION)
|
|
# Eventually, it is hoped that the decompiler will just handle these.
|
|
# In the meantime, lets try to rewrite so to help the decompiler out.
|
|
#
|
|
# Due to compiler optimizations, this can sometimes lead to bad results
|
|
# on 8051 derivatives. E.g, jumps to the middle of the fused instruction.
|
|
|
|
define token Fuse4ByteToken (32)
|
|
f4op1 = (24,31)
|
|
f4op1imm8 = (16,23)
|
|
f4op2 = (8,15)
|
|
f4op2imm8 = (0,7)
|
|
;
|
|
|
|
f4imm16: val is f4op1imm8 & f4op2imm8 [ val = (f4op2imm8 << 8) | f4op1imm8; ] { tmp:2 = val; export tmp; }
|
|
|
|
# Just do r7 r6 for now
|
|
:mov_fused R6R7,"#"f4imm16 is f4op1=0x7f & f4op2=0x7e & R6R7 & f4imm16 {
|
|
R6R7 = f4imm16;
|
|
}
|
|
@endif
|
|
|