1650 lines
69 KiB
Plaintext
1650 lines
69 KiB
Plaintext
#
|
|
# TI MSP430
|
|
#
|
|
# Texas Instruments microcontroller 16-bit CPU
|
|
|
|
|
|
#
|
|
# Memory Architecture
|
|
#
|
|
|
|
define endian=$(ENDIAN);
|
|
define alignment=2;
|
|
define space RAM type=ram_space size=$(REG_SIZE) default;
|
|
define space register type=register_space size=2;
|
|
|
|
#
|
|
# General Registers
|
|
#
|
|
define register offset=0x0000 size=$(REG_SIZE) [
|
|
PC # R0 # Program Counter
|
|
SP # R1 # Stack Pointer
|
|
SR # R2 # Status Register
|
|
R3 # R3 # Constant Generator
|
|
|
|
#Available for general use:
|
|
R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15
|
|
|
|
#None:
|
|
None
|
|
];
|
|
|
|
@if REG_SIZE == "4"
|
|
|
|
define register offset=0x0000 size=2 [
|
|
PC_16 _ SP_16 _ SR_16 _ R3_16 _ R4_16 _ R5_16 _ R6_16 _ R7_16 _
|
|
R8_16 _ R9_16 _ R10_16 _ R11_16 _ R12_16 _ R13_16 _ R14_16 _ R15_16 _
|
|
|
|
];
|
|
|
|
define register offset=0x0000 size=1 [
|
|
PC_lo PC_hi _ _ # R0 # Program Counter
|
|
SP_lo SP_hi _ _ # R1 # Stack Pointer
|
|
SR_lo SR_hi _ _ # R2 # Status Register
|
|
R3_lo R3_hi _ _ # R3 # Constant Generator
|
|
|
|
#Available for general use:
|
|
R4_lo R4_hi _ _
|
|
R5_lo R5_hi _ _
|
|
R6_lo R6_hi _ _
|
|
R7_lo R7_hi _ _
|
|
R8_lo R8_hi _ _
|
|
R9_lo R9_hi _ _
|
|
R10_lo R10_hi _ _
|
|
R11_lo R11_hi _ _
|
|
R12_lo R12_hi _ _
|
|
R13_lo R13_hi _ _
|
|
R14_lo R14_hi _ _
|
|
R15_lo R15_hi _ _
|
|
|
|
#None:
|
|
None_lo None_hi _ _
|
|
];
|
|
@else
|
|
|
|
define register offset=0x0000 size=1 [
|
|
PC_lo PC_hi # R0 # Program Counter
|
|
SP_lo SP_hi # R1 # Stack Pointer
|
|
SR_lo SR_hi # R2 # Status Register
|
|
R3_lo R3_hi # R3 # Constant Generator
|
|
|
|
#Available for general use:
|
|
R4_lo R4_hi
|
|
R5_lo R5_hi
|
|
R6_lo R6_hi
|
|
R7_lo R7_hi
|
|
R8_lo R8_hi
|
|
R9_lo R9_hi
|
|
R10_lo R10_hi
|
|
R11_lo R11_hi
|
|
R12_lo R12_hi
|
|
R13_lo R13_hi
|
|
R14_lo R14_hi
|
|
R15_lo R15_hi
|
|
|
|
#None:
|
|
None_lo None_hi
|
|
];
|
|
|
|
@endif
|
|
|
|
define register offset=0x1000 size=4 contextreg;
|
|
define context contextreg
|
|
# NOTE: Only instructions that don't use immediates (except ones from constant generator) can
|
|
# use the repeat feature.
|
|
# NOTE: The POPM/PUSM have a starting register & # of register to pop/push. We need to track
|
|
# that info in context for the subtables that do the work.
|
|
ctx_isHi=(0,0) noflow # Used in pspec to flag msp430 instruction > 64k
|
|
ctx_al=(1,1) noflow # extension word al field
|
|
ctx_ctregdest=(2,5) noflow # extension word dest register/immediate field
|
|
ctx_ctregdests=(2,5) signed noflow # signed version of above
|
|
ctx_repreg=(2,5) noflow # register repeat count comes from.
|
|
ctx_regsrc=(6,9) noflow # extension word src register/immediate field
|
|
ctx_regsrcs=(6,9) signed noflow # signed version of above
|
|
ctx_zc=(10,10) noflow # extension word zero carry field
|
|
ctx_num=(11,11) noflow # is repetition field a # or register
|
|
ctx_haveext=(12,14) noflow # used to track type of extension word used
|
|
ctx_popreg_set=(15,18) noflow # used to set register for POPM/PUSHM instructions
|
|
ctx_popreg=(15,18) noflow # display register, linked for POPM/PUSHM instructions
|
|
ctx_count=(19,22) noflow # tracks count of registers for POPM/PUSHM
|
|
ctx_mreg=(23,26) noflow # register being accessed in POPM/PUSHM
|
|
;
|
|
|
|
define register offset=0x2000 size=1 [ CNT ];
|
|
|
|
#
|
|
# Tokens
|
|
#
|
|
define token instr16(16)
|
|
op16_0_8 = (0, 7)
|
|
op16_4_4 = (4, 7)
|
|
op16_0_4 = (0, 3)
|
|
op16_7_9 = (7, 15)
|
|
op16_8_4 = (8, 11)
|
|
op16_8_8 = (8, 15)
|
|
op16_12_4 = (12, 15)
|
|
opext_11_5 = (11, 15)
|
|
op16_7_1 = (7, 7)
|
|
op16_13_3 = (13, 15)
|
|
|
|
src = (0, 3)
|
|
dest = (0, 3)
|
|
|
|
as = (4, 5)
|
|
bow = (6, 6)
|
|
insid = (4, 7)
|
|
insidbig = (4, 9)
|
|
reg16_0_4 = (0, 3)
|
|
dest_0_4 = (0, 3)
|
|
imm_0_4 = (0, 4)
|
|
reg_Direct16_0_4 = (0, 3)
|
|
reg_Direct16_0_4W = (0, 3)
|
|
reg_Indexed16_0_4 = (0, 3)
|
|
reg_InDirect16_0_4 = (0, 3)
|
|
dest_Direct16_0_4 = (0, 3)
|
|
dest_Indexed16_0_4 = (0, 3)
|
|
dest_Direct_lo = (0, 3)
|
|
dest_Direct_hi = (0, 3)
|
|
|
|
condition = (10, 12)
|
|
|
|
off16 = (0, 9) signed
|
|
off16_8_2 = (8, 9)
|
|
off16_4_4 = (4, 7)
|
|
off16_0_4 = (0, 3)
|
|
|
|
zc = (8, 8)
|
|
ad = (7, 7)
|
|
al = (6, 6)
|
|
imm_4_4 = (4, 7)
|
|
imm_8_4 = (8, 11)
|
|
src_8_4 = (8, 11)
|
|
src16_8_4 = (8, 11)
|
|
src_Direct16_8_4 = (8, 11)
|
|
reg_Direct16_8_4W = (8, 11)
|
|
src_InDirect16_8_4 = (8, 11)
|
|
src_Indexed16_8_4 = (8, 11)
|
|
src_Direct_lo = (8, 11)
|
|
src_Direct_hi = (8, 11)
|
|
src_ext = (7, 10)
|
|
rrn = (10, 11)
|
|
|
|
imm_0_16 = (0, 15)
|
|
imms_0_16 = (0, 15) signed
|
|
indexExtWord16_0_16 = (0, 15)
|
|
indexExtWord16_0_16s = (0, 15) signed
|
|
indexExt2Word16_0_16 = (0, 15)
|
|
indexExt2Word16_0_16s = (0, 15) signed
|
|
;
|
|
|
|
|
|
#
|
|
# Attach(s)
|
|
#
|
|
attach variables [ src_8_4
|
|
dest_0_4
|
|
reg_Direct16_0_4
|
|
src_Direct16_8_4
|
|
dest_Direct16_0_4
|
|
ctx_popreg
|
|
ctx_repreg ] [ PC SP SR R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ];
|
|
|
|
attach variables [ dest_Direct_lo src_Direct_lo] [ PC_lo SP_lo SR_lo _ R4_lo R5_lo R6_lo R7_lo
|
|
R8_lo R9_lo R10_lo R11_lo R12_lo R13_lo R14_lo R15_lo ];
|
|
attach variables [ dest_Direct_hi src_Direct_hi] [ PC_hi SP_hi SR_hi _ R4_hi R5_hi R6_hi R7_hi
|
|
R8_hi R9_hi R10_hi R11_hi R12_hi R13_hi R14_hi R15_hi ];
|
|
|
|
attach variables [ reg_Indexed16_0_4
|
|
src_Indexed16_8_4
|
|
dest_Indexed16_0_4 ] [ None SP _ _ R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ];
|
|
|
|
attach variables [ reg_InDirect16_0_4
|
|
src_InDirect16_8_4 ] [ PC SP _ _ R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ];
|
|
|
|
@if REG_SIZE == "4"
|
|
attach variables [reg_Direct16_0_4W reg_Direct16_8_4W] [PC_16 SP_16 SR_16 _ R4_16 R5_16 R6_16 R7_16 R8_16 R9_16 R10_16 R11_16 R12_16 R13_16 R14_16 R15_16];
|
|
@else
|
|
attach variables [reg_Direct16_0_4W reg_Direct16_8_4W] [PC SP SR _ R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15];
|
|
@endif
|
|
|
|
SRC16_8_4: src_Direct16_8_4 is src_Direct16_8_4 & reg_Direct16_8_4W {export reg_Direct16_8_4W;}
|
|
DST16_0_4: dest_Direct16_0_4 is dest_Direct16_0_4 & reg_Direct16_0_4W {export reg_Direct16_0_4W;}
|
|
SRC8_8_4: src_Direct16_8_4 is src_Direct16_8_4 & src_Direct_lo {export src_Direct_lo;}
|
|
DST8_0_4: reg_Direct16_0_4 is reg_Direct16_0_4 & dest_Direct_lo {export dest_Direct_lo;}
|
|
|
|
define pcodeop bcd_add; # Binary coded decimal (BCD) addition
|
|
####################################
|
|
# Status Register (SR) Map
|
|
####################################
|
|
# b15-b9: Reserved
|
|
# b8: V (overflow bit)
|
|
# b7: SCG1 (System Clock generator 1)
|
|
# b6: SCG0 (System Clock generator 0)
|
|
# b5: OSCOFF (Oscillator Off)
|
|
# b4: CPUOFF (CPU off)
|
|
# b3: GIE (General Interrupt Enable)
|
|
# b2: N (Negative Bit) (Word = bit 15, Byte = bit 7)(sign bit)
|
|
# b1: Z (Zero Bit)
|
|
# b0: C (Carry Bit)
|
|
####################################
|
|
|
|
@define CARRY "SR[0,1]"
|
|
@define ZERO "SR[1,1]"
|
|
@define SIGN "SR[2,1]"
|
|
@define OVERFLOW "SR[8,1]"
|
|
@define GIE "SR[3,1]"
|
|
|
|
#
|
|
# Sub Constructors
|
|
#
|
|
#-----------------------------------------------
|
|
# B/W: Byte or Word operation
|
|
# 0: Word Operation
|
|
# 1: Byte Operation
|
|
#-----------------------------------------------
|
|
|
|
@if REG_SIZE == "4"
|
|
AMASK: val is ctx_isHi=1 [ val = 0xFFFF; ] { export *[const]:4 val; }
|
|
AMASK: val is ctx_isHi=0 [ val = 0xFFFFF; ] { export *[const]:4 val; }
|
|
@else
|
|
AMASK: val is epsilon [ val = 0xFFFF; ] { export *[const]:2 val; }
|
|
@endif
|
|
|
|
#-----------------------------------------------
|
|
#
|
|
# REGISTER (REG)
|
|
#
|
|
# The REG modes are used for the 1 operand form instructions
|
|
#
|
|
#-----------------------------------------------
|
|
REG_W_AS: DST16_0_4 is DST16_0_4 & as=0x0 & bow=0x0 {export DST16_0_4;} # Word/Register Direct (Rn):
|
|
REG_W_AS: indexExtWord16_0_16s^"("^reg_Indexed16_0_4^")" is reg_Indexed16_0_4 & as=0x1 & bow=0x0 & AMASK ; indexExtWord16_0_16s {tmp:$(REG_SIZE) = (reg_Indexed16_0_4 + indexExtWord16_0_16s) & AMASK; export *:2 tmp;}
|
|
REG_W_AS: "@"^reg_InDirect16_0_4 is reg_InDirect16_0_4 & as=0x2 & bow=0x0 {export *:2 reg_InDirect16_0_4;} # Word/Register Indirect (@Rn):
|
|
REG_W_AS: "@"^reg_InDirect16_0_4^"+" is reg_InDirect16_0_4 & as=0x3 & bow=0x0 {export *:2 reg_InDirect16_0_4;} # Word/Register Indirect Autoincrement (@Rn+):
|
|
REG_W_AS: labelCalc is reg16_0_4=0x0 & as=0x1 & bow=0x0 & AMASK; indexExtWord16_0_16 [labelCalc = inst_start + 2 + indexExtWord16_0_16; ] {tmp:$(REG_SIZE) = labelCalc & AMASK; export *:2 tmp; } # Symbolic
|
|
REG_W_AS: "#"^indexExtWord16_0_16 is reg16_0_4=0x0 & as=0x3 & bow=0x0 ; indexExtWord16_0_16 {export *[const]:2 indexExtWord16_0_16; } # Immediate
|
|
REG_W_AS: "&"^indexExtWord16_0_16 is reg16_0_4=0x2 & as=0x1 & bow=0x0 ; indexExtWord16_0_16 {export *:2 indexExtWord16_0_16; } # Absolute
|
|
REG_W_AS: "#4" is reg16_0_4=0x2 & as=0x2 & bow=0x0 { export 4:2;} # Constant
|
|
REG_W_AS: "#8" is reg16_0_4=0x2 & as=0x3 & bow=0x0 { export 8:2;} # Constant
|
|
REG_W_AS: "#0" is reg16_0_4=0x3 & as=0x0 & bow=0x0 { export 0:2;} # Constant
|
|
REG_W_AS: "#1" is reg16_0_4=0x3 & as=0x1 & bow=0x0 { export 1:2;} # Constant
|
|
REG_W_AS: "#2" is reg16_0_4=0x3 & as=0x2 & bow=0x0 { export 2:2;} # Constant
|
|
REG_W_AS: "#-1" is reg16_0_4=0x3 & as=0x3 & bow=0x0 { export 0xffff:2;} # Constant
|
|
|
|
REG_W_AS_DEST: DST16_0_4 is DST16_0_4 & as=0x0 & bow=0x0 {export DST16_0_4;} # Word/Register Direct (Rn):
|
|
REG_W_AS_DEST: indexExtWord16_0_16s^"("^reg_Indexed16_0_4^")" is reg_Indexed16_0_4 & as=0x1 & bow=0x0 & AMASK ; indexExtWord16_0_16s {tmp:$(REG_SIZE) = (reg_Indexed16_0_4 + indexExtWord16_0_16s) & AMASK; export *:2 tmp;}
|
|
REG_W_AS_DEST: "@"^reg_InDirect16_0_4 is reg_InDirect16_0_4 & as=0x2 & bow=0x0 {export *:2 reg_InDirect16_0_4;} # Word/Register Indirect (@Rn):
|
|
REG_W_AS_DEST: "@"^reg_InDirect16_0_4^"+" is reg_InDirect16_0_4 & as=0x3 & bow=0x0 {export *:2 reg_InDirect16_0_4;} # Word/Register Indirect Autoincrement (@Rn+):
|
|
REG_W_AS_DEST: labelCalc is reg16_0_4=0x0 & as=0x1 & bow=0x0 & AMASK ; indexExtWord16_0_16 [labelCalc = inst_start + 2 + indexExtWord16_0_16; ] {tmp:$(REG_SIZE) = labelCalc & AMASK;export *:2 tmp; } # Symbolic
|
|
REG_W_AS_DEST: "&"^indexExtWord16_0_16 is reg16_0_4=0x2 & as=0x1 & bow=0x0 ; indexExtWord16_0_16 {export *:2 indexExtWord16_0_16; } # Absolute
|
|
|
|
#-----------------------------------------------
|
|
REG_B_AS: DST8_0_4 is DST8_0_4 & as=0x0 & bow=0x1 { export DST8_0_4;} # Word/Register Direct (Rn):
|
|
REG_B_AS: indexExtWord16_0_16s^"("^reg_Indexed16_0_4^")" is reg_Indexed16_0_4 & as=0x1 & bow=0x1 & AMASK ; indexExtWord16_0_16s {tmp:$(REG_SIZE) = (reg_Indexed16_0_4 + indexExtWord16_0_16s) & AMASK; export *:1 tmp;}
|
|
REG_B_AS: "@"^reg_InDirect16_0_4 is reg_InDirect16_0_4 & as=0x2 & bow=0x1 {export *:1 reg_InDirect16_0_4;} # Word/Register Indirect (@Rn):
|
|
REG_B_AS: "@"^reg_InDirect16_0_4^"+" is reg_InDirect16_0_4 & as=0x3 & bow=0x1 {export *:1 reg_InDirect16_0_4;} # Word/Register Indirect Autoincrement (@Rn+):
|
|
REG_B_AS: labelCalc is reg16_0_4=0x0 & as=0x1 & bow=0x1 & AMASK ; indexExtWord16_0_16 [labelCalc = inst_start + 2 + indexExtWord16_0_16; ] {tmp:$(REG_SIZE) = labelCalc & AMASK;export *:1 tmp; } # Symbolic
|
|
REG_B_AS: "#"^indexExtWord16_0_16 is reg16_0_4=0x0 & as=0x3 & bow=0x1 ; indexExtWord16_0_16 { export *[const]:1 indexExtWord16_0_16; } # Immediate
|
|
REG_B_AS: "&"^indexExtWord16_0_16 is reg16_0_4=0x2 & as=0x1 & bow=0x1 ; indexExtWord16_0_16 {export *:1 indexExtWord16_0_16; } # Absolute
|
|
REG_B_AS: "#4" is reg16_0_4=0x2 & as=0x2 & bow=0x1 { export 4:1;} # Constant
|
|
REG_B_AS: "#8" is reg16_0_4=0x2 & as=0x3 & bow=0x1 { export 8:1;} # Constant
|
|
REG_B_AS: "#0" is reg16_0_4=0x3 & as=0x0 & bow=0x1 { export 0:1;} # Constant
|
|
REG_B_AS: "#1" is reg16_0_4=0x3 & as=0x1 & bow=0x1 { export 1:1;} # Constant
|
|
REG_B_AS: "#2" is reg16_0_4=0x3 & as=0x2 & bow=0x1 { export 2:1;} # Constant
|
|
REG_B_AS: "#-1" is reg16_0_4=0x3 & as=0x3 & bow=0x1 { export 0xff:1;} # Constant
|
|
|
|
REG_B_AS_DEST: DST8_0_4 is DST8_0_4 & as=0x0 & bow=0x1 { export DST8_0_4;} # Word/Register Direct (Rn):
|
|
REG_B_AS_DEST: indexExtWord16_0_16s^"("^reg_Indexed16_0_4^")" is reg_Indexed16_0_4 & as=0x1 & bow=0x1 & AMASK ; indexExtWord16_0_16s {tmp:$(REG_SIZE) = (reg_Indexed16_0_4 + indexExtWord16_0_16s) & AMASK; export *:1 tmp;}
|
|
REG_B_AS_DEST: "@"^reg_InDirect16_0_4 is reg_InDirect16_0_4 & as=0x2 & bow=0x1 {export *:1 reg_InDirect16_0_4;} # Word/Register Indirect (@Rn):
|
|
REG_B_AS_DEST: "@"^reg_InDirect16_0_4^"+" is reg_InDirect16_0_4 & as=0x3 & bow=0x1 {export *:1 reg_InDirect16_0_4;} # Word/Register Indirect Autoincrement (@Rn+):
|
|
REG_B_AS_DEST: labelCalc is reg16_0_4=0x0 & as=0x1 & bow=0x1 & AMASK ; indexExtWord16_0_16 [labelCalc = inst_start + 2 + indexExtWord16_0_16; ] {tmp:$(REG_SIZE) = labelCalc & AMASK;export *:1 tmp; } # Symbolic
|
|
REG_B_AS_DEST: "&"^indexExtWord16_0_16 is reg16_0_4=0x2 & as=0x1 & bow=0x1 ; indexExtWord16_0_16 {export *:1 indexExtWord16_0_16; } # Absolute
|
|
|
|
#-----------------------------------------------
|
|
#
|
|
# SOURCE (SRC)
|
|
#
|
|
#-----------------------------------------------
|
|
SRC_W_AS: SRC16_8_4 is SRC16_8_4 & as=0x0 & bow=0x0 {export SRC16_8_4;} # Word/Register Direct (Rn):
|
|
SRC_W_AS: indexExtWord16_0_16s^"("^src_Indexed16_8_4^")" is src_Indexed16_8_4 & as=0x1 & bow=0x0 & AMASK ; indexExtWord16_0_16s {tmp:$(REG_SIZE) = (src_Indexed16_8_4 + indexExtWord16_0_16s) & AMASK; export *:2 tmp;}
|
|
SRC_W_AS: "@"^src_InDirect16_8_4 is src_InDirect16_8_4 & as=0x2 & bow=0x0 {export *:2 src_InDirect16_8_4;} # Word/Register Indirect (@Rn):
|
|
SRC_W_AS: "@"^src_InDirect16_8_4^"+" is src_InDirect16_8_4 & as=0x3 & bow=0x0 {export *:2 src_InDirect16_8_4;} # Word/Register Indirect Autoincrement (@Rn+):
|
|
SRC_W_AS: labelCalc is src16_8_4=0x0 & as=0x1 & bow=0x0 & AMASK ; indexExtWord16_0_16 [labelCalc = inst_start + 2 + indexExtWord16_0_16; ] {tmp:$(REG_SIZE) = labelCalc & AMASK;export *:2 tmp; } # Symbolic
|
|
SRC_W_AS: "#"^indexExtWord16_0_16 is src16_8_4=0x0 & as=0x3 & bow=0x0 ; indexExtWord16_0_16 {export *[const]:2 indexExtWord16_0_16; } # Immediate
|
|
SRC_W_AS: "&"^indexExtWord16_0_16 is src16_8_4=0x2 & as=0x1 & bow=0x0 ; indexExtWord16_0_16 {export *:2 indexExtWord16_0_16; } # Absolute
|
|
SRC_W_AS: "#4" is src16_8_4=0x2 & as=0x2 & bow=0x0 { export 4:2; } # Constant
|
|
SRC_W_AS: "#8" is src16_8_4=0x2 & as=0x3 & bow=0x0 { export 8:2; } # Constant
|
|
SRC_W_AS: "#0" is src16_8_4=0x3 & as=0x0 & bow=0x0 { export 0:2; } # Constant
|
|
SRC_W_AS: "#1" is src16_8_4=0x3 & as=0x1 & bow=0x0 { export 1:2; } # Constant
|
|
SRC_W_AS: "#2" is src16_8_4=0x3 & as=0x2 & bow=0x0 { export 2:2; } # Constant
|
|
SRC_W_AS: "#-1" is src16_8_4=0x3 & as=0x3 & bow=0x0 { export 0xffff:2; } # Constant
|
|
#-----------------------------------------------
|
|
SRC_B_AS: SRC8_8_4 is SRC8_8_4 & as=0x0 & bow=0x1 { export SRC8_8_4;} # Word/Register Direct (Rn):
|
|
SRC_B_AS: indexExtWord16_0_16s^"("^src_Indexed16_8_4^")" is src_Indexed16_8_4 & as=0x1 & bow=0x1 & AMASK ; indexExtWord16_0_16s {tmp:$(REG_SIZE) = (src_Indexed16_8_4 + indexExtWord16_0_16s) & AMASK; export *:1 tmp;}
|
|
SRC_B_AS: "@"^src_InDirect16_8_4 is src_InDirect16_8_4 & as=0x2 & bow=0x1 {export *:1 src_InDirect16_8_4;} # Word/Register Indirect (@Rn):
|
|
SRC_B_AS: "@"^src_InDirect16_8_4^"+" is src_InDirect16_8_4 & as=0x3 & bow=0x1 {export *:1 src_InDirect16_8_4;} # Word/Register Indirect Autoincrement (@Rn+):
|
|
SRC_B_AS: labelCalc is src16_8_4=0x0 & as=0x1 & bow=0x1 & AMASK ; indexExtWord16_0_16 [labelCalc = inst_start + 2 + indexExtWord16_0_16; ] {tmp:$(REG_SIZE) = labelCalc & AMASK;export *:1 tmp; } # Symbolic
|
|
SRC_B_AS: "#"^indexExtWord16_0_16 is src16_8_4=0x0 & as=0x3 & bow=0x1 ; indexExtWord16_0_16 {export *[const]:1 indexExtWord16_0_16;} # Immediate
|
|
SRC_B_AS: "&"^indexExtWord16_0_16 is src16_8_4=0x2 & as=0x1 & bow=0x1 ; indexExtWord16_0_16 {export *:1 indexExtWord16_0_16; } # Absolute
|
|
SRC_B_AS: "#4" is src16_8_4=0x2 & as=0x2 & bow=0x1 { export 4:1; } # Constant
|
|
SRC_B_AS: "#8" is src16_8_4=0x2 & as=0x3 & bow=0x1 { export 8:1; } # Constant
|
|
SRC_B_AS: "#0" is src16_8_4=0x3 & as=0x0 & bow=0x1 { export 0:1; } # Constant
|
|
SRC_B_AS: "#1" is src16_8_4=0x3 & as=0x1 & bow=0x1 { export 1:1; } # Constant
|
|
SRC_B_AS: "#2" is src16_8_4=0x3 & as=0x2 & bow=0x1 { export 2:1; } # Constant
|
|
SRC_B_AS: "#-1" is src16_8_4=0x3 & as=0x3 & bow=0x1 { export 0xff:1; } # Constant
|
|
|
|
#-----------------------------------------------
|
|
#
|
|
# DESTINATION (DEST)
|
|
#
|
|
#-----------------------------------------------
|
|
DEST_W_AD: DST16_0_4 is DST16_0_4 & ad=0x0 & bow=0x0
|
|
{export DST16_0_4;} # Word/Register Direct (Rn):
|
|
|
|
DEST_W_AD: indexExtWord16_0_16s^"("^dest_Indexed16_0_4^")" is dest_Indexed16_0_4 & ad=0x1 & bow=0x0 & AMASK ; indexExtWord16_0_16s
|
|
{tmp:$(REG_SIZE) = (dest_Indexed16_0_4 + indexExtWord16_0_16s) & AMASK; export *:2 tmp;}
|
|
#---Depends on SRC ---#
|
|
DEST_W_AD: indexExt2Word16_0_16s^"("^dest_Indexed16_0_4^")" is dest_Indexed16_0_4 & ad=0x1 & bow=0x0 & AMASK & as=0x1 & ((src16_8_4>=0x0 & src16_8_4<=0x2) | (src16_8_4>=0x4 & src16_8_4<=0xF)) ; indexExtWord16_0_16 ; indexExt2Word16_0_16s
|
|
{tmp:$(REG_SIZE) = (dest_Indexed16_0_4 + indexExt2Word16_0_16s) & AMASK; export *:2 tmp;}
|
|
DEST_W_AD: indexExt2Word16_0_16s^"("^dest_Indexed16_0_4^")" is dest_Indexed16_0_4 & ad=0x1 & bow=0x0 & AMASK & as=0x3 & src16_8_4=0x0 ; indexExtWord16_0_16 ; indexExt2Word16_0_16s
|
|
{tmp:$(REG_SIZE) = (dest_Indexed16_0_4 + indexExt2Word16_0_16s) & AMASK; export *:2 tmp;}
|
|
#---End of Depend ----#
|
|
|
|
DEST_W_AD: labelCalc is dest=0x0 & ad=0x1 & bow=0x0 & AMASK ; indexExtWord16_0_16s [labelCalc = inst_start + 2 + indexExtWord16_0_16s; ]
|
|
{tmp:$(REG_SIZE) = labelCalc & AMASK;export *:2 tmp; } # Symbolic
|
|
#---Depends on SRC ---#
|
|
DEST_W_AD: labelCalc is dest=0x0 & ad=0x1 & bow=0x0 & AMASK & as=0x1 & ((src16_8_4>=0x0 & src16_8_4<=0x2) | (src16_8_4>=0x4 & src16_8_4<=0xF)) ; indexExtWord16_0_16 ; indexExt2Word16_0_16s [labelCalc = inst_start + 4 + indexExt2Word16_0_16s; ]
|
|
{tmp:$(REG_SIZE) = labelCalc & AMASK;export *:2 tmp; } # Symbolic
|
|
DEST_W_AD: labelCalc is dest=0x0 & ad=0x1 & bow=0x0 & AMASK & as=0x3 & src16_8_4=0x0 ; indexExtWord16_0_16 ; indexExt2Word16_0_16s [labelCalc = inst_start + 4 + indexExt2Word16_0_16s; ]
|
|
{tmp:$(REG_SIZE) = labelCalc & AMASK;export *:2 tmp; } # Symbolic
|
|
#---End of Depend ----#
|
|
|
|
DEST_W_AD: "&"^indexExtWord16_0_16 is dest=0x2 & ad=0x1 & bow=0x0 ; indexExtWord16_0_16
|
|
{export *:2 indexExtWord16_0_16; } # Absolute
|
|
#---Depends on SRC ---#
|
|
DEST_W_AD: "&"^indexExt2Word16_0_16 is dest=0x2 & ad=0x1 & bow=0x0 & as=0x1 & ((src16_8_4>=0x0 & src16_8_4<=0x2) | (src16_8_4>=0x4 & src16_8_4<=0xF)) ; indexExtWord16_0_16 ; indexExt2Word16_0_16
|
|
{export *:2 indexExt2Word16_0_16; } # Absolute
|
|
DEST_W_AD: "&"^indexExt2Word16_0_16 is dest=0x2 & ad=0x1 & bow=0x0 & as=0x3 & src16_8_4=0x0 ; indexExtWord16_0_16 ; indexExt2Word16_0_16
|
|
{export *:2 indexExt2Word16_0_16; } # Absolute
|
|
#---End of Depend ----#
|
|
|
|
#-----------------------------------------------
|
|
DEST_B_AD: DST8_0_4 is DST8_0_4 & dest_Direct_lo & ad=0x0 & bow=0x1
|
|
{ export DST8_0_4; } # Word/Register Direct (Rn):
|
|
|
|
DEST_B_AD: indexExtWord16_0_16s^"("^dest_Indexed16_0_4^")" is dest_Indexed16_0_4 & ad=0x1 & bow=0x1 & AMASK ; indexExtWord16_0_16s
|
|
{ tmp:$(REG_SIZE) = (dest_Indexed16_0_4 + indexExtWord16_0_16s) & AMASK; export *:1 tmp;}
|
|
#---Depends on SRC ---#
|
|
DEST_B_AD: indexExt2Word16_0_16s^"("^dest_Indexed16_0_4^")" is dest_Indexed16_0_4 & ad=0x1 & bow=0x1 & AMASK & as=0x1 & ((src16_8_4>=0x0 & src16_8_4<=0x2) | (src16_8_4>=0x4 & src16_8_4<=0xF)) ; indexExtWord16_0_16 ; indexExt2Word16_0_16s
|
|
{ tmp:$(REG_SIZE) = (dest_Indexed16_0_4 + indexExt2Word16_0_16s) & AMASK; export *:1 tmp;}
|
|
DEST_B_AD: indexExt2Word16_0_16s^"("^dest_Indexed16_0_4^")" is dest_Indexed16_0_4 & ad=0x1 & bow=0x1 & AMASK & as=0x3 & src16_8_4=0x0 ; indexExtWord16_0_16 ; indexExt2Word16_0_16s
|
|
{ tmp:$(REG_SIZE) = (dest_Indexed16_0_4 + indexExt2Word16_0_16s) & AMASK; export *:1 tmp;}
|
|
#---End of Depend ----#
|
|
|
|
DEST_B_AD: labelCalc is dest=0x0 & ad=0x1 & bow=0x1 & AMASK ; indexExtWord16_0_16s [labelCalc = inst_start + 2 + indexExtWord16_0_16s; ]
|
|
{tmp:$(REG_SIZE) = labelCalc & AMASK; export *:1 tmp; } # Symbolic
|
|
#---Depends on SRC ---#
|
|
DEST_B_AD: labelCalc is dest=0x0 & ad=0x1 & bow=0x1 & AMASK & as=0x1 & ((src16_8_4>=0x0 & src16_8_4<=0x2) | (src16_8_4>=0x4 & src16_8_4<=0xF)) ; indexExtWord16_0_16 ; indexExt2Word16_0_16s [labelCalc = inst_start + 4 + indexExt2Word16_0_16s; ]
|
|
{tmp:$(REG_SIZE) = labelCalc & AMASK;export *:1 tmp; } # Symbolic
|
|
DEST_B_AD: labelCalc is dest=0x0 & ad=0x1 & bow=0x1 & AMASK & as=0x3 & src16_8_4=0x0 ; indexExtWord16_0_16 ; indexExt2Word16_0_16s [labelCalc = inst_start + 4 + indexExt2Word16_0_16s; ]
|
|
{tmp:$(REG_SIZE) = labelCalc & AMASK;export *:1 tmp; } # Symbolic
|
|
#---End of Depend ----#
|
|
|
|
DEST_B_AD: "&"^indexExtWord16_0_16 is dest=0x2 & ad=0x1 & bow=0x1 ; indexExtWord16_0_16
|
|
{export *:1 indexExtWord16_0_16; } # Absolute
|
|
#---Depends on SRC ---#
|
|
DEST_B_AD: "&"^indexExt2Word16_0_16 is dest=0x2 & ad=0x1 & bow=0x1 & as=0x1 & ((src16_8_4>=0x0 & src16_8_4<=0x2) | (src16_8_4>=0x4 & src16_8_4<=0xF)) ; indexExtWord16_0_16 ; indexExt2Word16_0_16
|
|
{export *:1 indexExt2Word16_0_16; } # Absolute
|
|
DEST_B_AD: "&"^indexExt2Word16_0_16 is dest=0x2 & ad=0x1 & bow=0x1 & as=0x3 & src16_8_4=0x0 ; indexExtWord16_0_16 ; indexExt2Word16_0_16
|
|
{export *:1 indexExt2Word16_0_16; } # Absolute
|
|
#---End of Depend ----#
|
|
|
|
|
|
# For handling constant operands in CALL and BR instructions.
|
|
DirectAddr: "#"^indexExtWord16_0_16 is indexExtWord16_0_16 {export *:$(REG_SIZE) indexExtWord16_0_16; }
|
|
|
|
tbl_bzero: is ad=0 & reg_Direct16_0_4 & dest_Direct_lo {ztmp:1 = dest_Direct_lo; reg_Direct16_0_4 = 0; dest_Direct_lo = ztmp; }
|
|
tbl_bzero: is epsilon {}
|
|
|
|
@if REG_SIZE == "4"
|
|
tbl_wzero: is ad=0 & reg_Direct16_0_4 & reg_Direct16_0_4W {ztmp:2 = reg_Direct16_0_4W; reg_Direct16_0_4 = 0; reg_Direct16_0_4W = ztmp; }
|
|
@endif
|
|
tbl_wzero: is epsilon {}
|
|
|
|
#
|
|
# Post Processing
|
|
# does correct increment of source register
|
|
# Also catches when PC is being stored to and does the correct branching
|
|
#
|
|
postRegIncrement: is as=0x3 & src16_8_4 & bow=0x0 & reg_InDirect16_0_4 { reg_InDirect16_0_4 = reg_InDirect16_0_4 + 2; }
|
|
postRegIncrement: is as=0x3 & src16_8_4 & bow=0x1 & reg_InDirect16_0_4 { reg_InDirect16_0_4 = reg_InDirect16_0_4 + 1; }
|
|
postRegIncrement: is as=0x3 & src16_8_4=1 & bow=0x1 & reg_InDirect16_0_4 { reg_InDirect16_0_4 = reg_InDirect16_0_4 + 2; }
|
|
postRegIncrement: is as=0x3 & src16_8_4=0 & bow=0x0 & reg_InDirect16_0_4 { } # PC is incremented by 2, but that is just to skip over the value
|
|
postRegIncrement: is as=0x3 & src16_8_4=0 & bow=0x1 & reg_InDirect16_0_4 { } # PC is incremented by 2, but that is just to skip over the value
|
|
postRegIncrement: is as=0x3 & src16_8_4=2 & bow=0x1 { }
|
|
postRegIncrement: is as=0x3 & src16_8_4=3 & bow=0x1 { }
|
|
postRegIncrement: is as=0x3 & src16_8_4=2 & bow=0x0 { }
|
|
postRegIncrement: is as=0x3 & src16_8_4=3 & bow=0x0 { }
|
|
postRegIncrement: is as & bow { }
|
|
|
|
# R2 and R3 are constant generators - post-increment not supported
|
|
postIncrement: is as=0x3 & ctx_haveext=0 & src16_8_4=2 & bow=0x0 & ctx_al=0
|
|
{ }
|
|
postIncrement: is as=0x3 & ctx_haveext=0 & src16_8_4=2 & bow=0x1 & ctx_al=0
|
|
{ }
|
|
postIncrement: is as=0x3 & ctx_haveext=0 & src16_8_4=3 & bow=0x0 & ctx_al=0
|
|
{ }
|
|
postIncrement: is as=0x3 & ctx_haveext=0 & src16_8_4=3 & bow=0x1 & ctx_al=0
|
|
{ }
|
|
postIncrement: is as=0x3 & src16_8_4=2 & bow=0x0
|
|
{ }
|
|
postIncrement: is as=0x3 & src16_8_4=2 & bow=0x1
|
|
{ }
|
|
postIncrement: is as=0x3 & src16_8_4=3 & bow=0x0
|
|
{ }
|
|
postIncrement: is as=0x3 & src16_8_4=3 & bow=0x1
|
|
{ }
|
|
|
|
postIncrement: is as=0x3 & src16_8_4=0 & bow=0x1 & src_InDirect16_8_4
|
|
{ } # PC is incremented by 2, but that is just to skip over the value
|
|
postIncrement: is as=0x3 & src16_8_4=0 & bow=0x0 & src_InDirect16_8_4
|
|
{ } # PC is incremented by 2, but that is just to skip over the value
|
|
|
|
postIncrement: is as=0x3 & src16_8_4 & bow=0x0 & src_InDirect16_8_4
|
|
{ src_InDirect16_8_4 = src_InDirect16_8_4 + 2; }
|
|
|
|
postIncrement: is as=0x3 & src16_8_4 & bow=0x1 & ctx_al=0 & src_InDirect16_8_4
|
|
{ src_InDirect16_8_4 = src_InDirect16_8_4 + 4; }
|
|
postIncrement: is as=0x3 & src16_8_4=1 & bow=0x1 & ctx_al=0 & src_InDirect16_8_4
|
|
{ src_InDirect16_8_4 = src_InDirect16_8_4 + 4; }
|
|
|
|
postIncrement: is as=0x3 & src16_8_4 & bow=0x1 & ctx_al=1 & src_InDirect16_8_4
|
|
{ src_InDirect16_8_4 = src_InDirect16_8_4 + 1; }
|
|
postIncrement: is as=0x3 & src16_8_4=1 & bow=0x1 & ctx_al=1 & src_InDirect16_8_4
|
|
{ src_InDirect16_8_4 = src_InDirect16_8_4 + 2; }
|
|
|
|
postIncrement: is as=0x3 & ctx_haveext=0 & src16_8_4 & bow=0x1 & ctx_al=0 & src_InDirect16_8_4
|
|
{ src_InDirect16_8_4 = src_InDirect16_8_4 + 1; }
|
|
postIncrement: is as=0x3 & ctx_haveext=0 & src16_8_4=1 & bow=0x1 & ctx_al=0 & src_InDirect16_8_4
|
|
{ src_InDirect16_8_4 = src_InDirect16_8_4 + 2; }
|
|
|
|
postIncrement: is as & src16_8_4 & bow
|
|
{ }
|
|
|
|
|
|
#
|
|
# Zero Extends if the store is byte oriented, and a register is being stored to
|
|
zeroExtend: is dest_Direct_lo & dest_Direct16_0_4
|
|
{ dest_Direct16_0_4 = zext(dest_Direct_lo); }
|
|
|
|
#
|
|
# Post processing when destination is the PC
|
|
#
|
|
postIncrementStore: is postIncrement & ad=0x0 & src_InDirect16_8_4 & as=0x3 & src16_8_4=1 & dest_Direct16_0_4=0x0 & bow=0x1 & ctx_al=1 & zeroExtend
|
|
{ build zeroExtend; build postIncrement; return [PC]; }
|
|
postIncrementStore: is postIncrement & ad=0x0 & dest_Direct16_0_4=0x0 & bow=0x1 & ctx_al=1 & zeroExtend
|
|
{ build zeroExtend; build postIncrement; goto [PC];}
|
|
postIncrementStore: is postIncrement & ad=0x0 & bow=0x1 & ctx_al=1 & zeroExtend
|
|
{ build zeroExtend; build postIncrement; }
|
|
|
|
postIncrementStore: is postIncrement & ctx_haveext=0 & ad=0x0 & src_InDirect16_8_4 & as=0x3 & src16_8_4=1 & dest_Direct16_0_4=0x0 & bow=0x1 & zeroExtend
|
|
{ build zeroExtend; build postIncrement; return [PC]; }
|
|
postIncrementStore: is postIncrement & ctx_haveext=0 & ad=0x0 & dest_Direct16_0_4=0x0 & bow=0x1 & zeroExtend
|
|
{ build zeroExtend; build postIncrement; goto [PC];}
|
|
postIncrementStore: is postIncrement & ctx_haveext=0 & ad=0x0 & bow=0x1 & zeroExtend
|
|
{ build zeroExtend; build postIncrement; }
|
|
|
|
|
|
postIncrementStore: is postIncrement & ad=0x0 & src_InDirect16_8_4 & as=0x3 & src16_8_4=1 & dest_Direct16_0_4=0x0
|
|
{ build postIncrement; return [PC]; }
|
|
postIncrementStore: is postIncrement & ad=0x0 & dest_Direct16_0_4=0x0
|
|
{ build postIncrement; goto [PC];}
|
|
postIncrementStore: is postIncrement & ad & bow
|
|
{ build postIncrement; }
|
|
|
|
#-----------------------------------------------
|
|
#
|
|
# JUMP CONDITION (JCND)
|
|
#
|
|
#-----------------------------------------------
|
|
|
|
JCND: "NE" is condition=0x0 {cndTst:1 = !$(ZERO); export cndTst;} # Not Equal/Zero (cleared)
|
|
JCND: "EQ" is condition=0x1 {cndTst:1 = $(ZERO); export cndTst;} # Equal/Zero (set)
|
|
JCND: "NC" is condition=0x2 {cndTst:1 = !$(CARRY); export cndTst;} # No Carry/Lower (cleared)
|
|
JCND: "C" is condition=0x3 {cndTst:1 = $(CARRY); export cndTst;} # Carry/Higher or same (set)
|
|
JCND: "N" is condition=0x4 {cndTst:1 = $(SIGN); export cndTst;} # Negative (set)
|
|
JCND: "GE" is condition=0x5 {cndTst:1 = ($(SIGN) == $(OVERFLOW)); export cndTst;} # Greater or equal (>=)
|
|
JCND: "L" is condition=0x6 {cndTst:1 = ($(SIGN) != $(OVERFLOW)); export cndTst;} # Less (<)
|
|
JCND: "MP" is condition=0x7 {cndTst:1 = 0x1; export cndTst;} # Unconditional
|
|
|
|
#-----------------------------------------------
|
|
#
|
|
# 10 BIT OFFSET
|
|
#
|
|
#-----------------------------------------------
|
|
|
|
OFFSET_10BIT: offset10 is off16 [offset10 = inst_start + 2 + off16 * 2; ]
|
|
{ export *:2 offset10;}
|
|
|
|
|
|
###################################################################################
|
|
#
|
|
# Single-operand arithmetic
|
|
#
|
|
# ------------------------------------------------------------------------------
|
|
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
# ------------------------------------------------------------------------------
|
|
# | 0 | 0 | 0 | 1 | 0 | 0 | opcode | B/W | As | register |
|
|
# ------------------------------------------------------------------------------
|
|
###################################################################################
|
|
|
|
###################################################################################
|
|
#
|
|
# RRC: Rotate right through carry
|
|
# ------------------------------------------------------------------------------
|
|
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
# ------------------------------------------------------------------------------
|
|
# | 0 | 0 | 0 | 1 | 0 | 0 | 000 | B/W | As | register |
|
|
:RRC^".W" REG_W_AS_DEST is ctx_haveext=0 & (op16_12_4=0x1 & op16_8_4=0x0 & op16_7_1=0x0 & bow=0x0 & tbl_wzero & postRegIncrement) ... & REG_W_AS_DEST {
|
|
# Operation Flags...
|
|
$(OVERFLOW) = ((REG_W_AS_DEST != 0x0) && ($(CARRY) == 0x1)); # V Flag
|
|
# Operation...
|
|
tmp:1 = $(CARRY);
|
|
$(CARRY) = REG_W_AS_DEST[0,1];
|
|
REG_W_AS_DEST = ((zext(tmp) << 0xF) | (REG_W_AS_DEST >> 0x1));
|
|
build tbl_wzero;
|
|
# Result Flags...
|
|
$(SIGN) = (REG_W_AS_DEST s< 0x0); # S Flag
|
|
$(ZERO) = (REG_W_AS_DEST == 0x0); # Z Flag
|
|
build postRegIncrement;
|
|
}
|
|
|
|
|
|
:RRC^".B" REG_B_AS_DEST is ctx_haveext=0 & (op16_12_4=0x1 & op16_8_4=0x0 & op16_7_1=0x0 & bow=0x1 & tbl_bzero & postRegIncrement) ... & REG_B_AS_DEST {
|
|
# Operation Flags...
|
|
$(OVERFLOW) = ((REG_B_AS_DEST != 0x0) && ($(CARRY) == 0x1)); # V Flag
|
|
# Operation...
|
|
tmp:1 = $(CARRY);
|
|
$(CARRY) = (REG_B_AS_DEST & 0x1);
|
|
REG_B_AS_DEST = ((tmp << 0x7) | (REG_B_AS_DEST >> 0x1));
|
|
build tbl_bzero;
|
|
# Result Flags...
|
|
$(SIGN) = (REG_B_AS_DEST s< 0x0); # S Flag
|
|
$(ZERO) = (REG_B_AS_DEST == 0x0); # Z Flag
|
|
build postRegIncrement;
|
|
}
|
|
|
|
|
|
###################################################################################
|
|
#
|
|
# SWPB: Swap bytes
|
|
# ------------------------------------------------------------------------------
|
|
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
# ------------------------------------------------------------------------------
|
|
# | 0 | 0 | 0 | 1 | 0 | 0 | 001 | 0 | As | register |
|
|
:SWPB REG_W_AS_DEST is ctx_haveext=0 & (op16_12_4=0x1 & op16_8_4=0x0 & op16_7_1=0x1 & bow=0x0 & tbl_wzero & postRegIncrement) ... & REG_W_AS_DEST {
|
|
lowByte:1 = REG_W_AS_DEST[0,8];
|
|
highByte:1 = REG_W_AS_DEST[8,8];
|
|
REG_W_AS_DEST = (((zext(lowByte)) << 0x8) | zext(highByte));
|
|
build tbl_wzero;
|
|
#Status bits are not affected
|
|
build postRegIncrement;
|
|
}
|
|
|
|
|
|
|
|
###################################################################################
|
|
#
|
|
# RRA: Rotate right arithmetic
|
|
# ------------------------------------------------------------------------------
|
|
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
# ------------------------------------------------------------------------------
|
|
# | 0 | 0 | 0 | 1 | 0 | 0 | 010 | B/W | As | register |
|
|
:RRA^".W" REG_W_AS_DEST is ctx_haveext=0 & (op16_12_4=0x1 & op16_8_4=0x1 & op16_7_1=0x0 & bow=0x0 & tbl_wzero & postRegIncrement) ... & REG_W_AS_DEST {
|
|
# Operation Flags...
|
|
$(OVERFLOW) = 0x0; # V Flag (reset)
|
|
# Operation...
|
|
$(CARRY) = REG_W_AS_DEST[0,1];
|
|
MSB:2 = REG_W_AS_DEST >> 0xF;
|
|
REG_W_AS_DEST = ((MSB << 0xF) | (REG_W_AS_DEST >> 0x1));
|
|
build tbl_wzero;
|
|
# Result Flags...
|
|
$(SIGN) = (REG_W_AS_DEST s< 0x0); # S Flag
|
|
$(ZERO) = (REG_W_AS_DEST == 0x0); # Z Flag
|
|
build postRegIncrement;
|
|
}
|
|
|
|
|
|
:RRA^".B" REG_B_AS_DEST is ctx_haveext=0 & (op16_12_4=0x1 & op16_8_4=0x1 & op16_7_1=0x0 & bow=0x1 & tbl_bzero & postRegIncrement) ... & REG_B_AS_DEST {
|
|
# Operation Flags...
|
|
$(OVERFLOW) = 0x0; # V Flag (reset)
|
|
# Operation...
|
|
$(CARRY) = (REG_B_AS_DEST & 0x1);
|
|
MSB:1 = REG_B_AS_DEST >> 0x7;
|
|
REG_B_AS_DEST = ((MSB << 0x7) | (REG_B_AS_DEST >> 0x1));
|
|
build tbl_bzero;
|
|
# Result Flags...
|
|
$(SIGN) = (REG_B_AS_DEST s< 0x0); # S Flag
|
|
$(ZERO) = (REG_B_AS_DEST == 0x0); # Z Flag
|
|
build postRegIncrement;
|
|
}
|
|
|
|
|
|
###################################################################################
|
|
#
|
|
# SXT: Sign extend byte to word
|
|
# ------------------------------------------------------------------------------
|
|
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
# ------------------------------------------------------------------------------
|
|
# | 0 | 0 | 0 | 1 | 0 | 0 | 011 | 0 | As | register |
|
|
:SXT REG_W_AS_DEST is ctx_haveext=0 & (op16_12_4=0x1 & op16_8_4=0x1 & op16_7_1=0x1 & bow=0x0 & tbl_wzero & postRegIncrement) ... & REG_W_AS_DEST {
|
|
# Operation Flags...
|
|
$(OVERFLOW) = 0x0; # V Flag
|
|
# Operation...
|
|
byteVal:1 = REG_W_AS_DEST[0,8];
|
|
REG_W_AS_DEST = sext(byteVal);
|
|
build tbl_wzero;
|
|
# Result Flags...
|
|
$(SIGN) = (REG_W_AS_DEST s< 0x0); # S Flag
|
|
$(ZERO) = (REG_W_AS_DEST == 0x0); # Z Flag
|
|
$(CARRY) = (REG_W_AS_DEST != 0x0); # C Flag
|
|
build postRegIncrement;
|
|
}
|
|
|
|
|
|
###################################################################################
|
|
#
|
|
# PUSH: Push value onto stack
|
|
# ------------------------------------------------------------------------------
|
|
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
# ------------------------------------------------------------------------------
|
|
# | 0 | 0 | 0 | 1 | 0 | 0 | 100 | B/W | As | register |
|
|
:PUSH^".W" REG_W_AS is ctx_haveext=0 & (op16_12_4=0x1 & op16_8_4=0x2 & op16_7_1=0x0 & bow=0x0 & postRegIncrement) ... & REG_W_AS {
|
|
SP = SP - 0x2;
|
|
*:2 SP = REG_W_AS;
|
|
#Status bits are not affected
|
|
build postRegIncrement;
|
|
}
|
|
|
|
:PUSH^".B" REG_B_AS is ctx_haveext=0 & (op16_12_4=0x1 & op16_8_4=0x2 & op16_7_1=0x0 & bow=0x1 & postRegIncrement) ... & REG_B_AS {
|
|
SP = SP - 0x2;
|
|
*:1 SP = REG_B_AS;
|
|
#Status bits are not affected
|
|
build postRegIncrement;
|
|
}
|
|
|
|
|
|
###################################################################################
|
|
#
|
|
# CALL: Subroutine call; push PC and move source to PC
|
|
# ------------------------------------------------------------------------------
|
|
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
# ------------------------------------------------------------------------------
|
|
# | 0 | 0 | 0 | 1 | 0 | 0 | 101 | 0 | As | register |
|
|
:CALL REG_W_AS is ctx_haveext=0 & (op16_12_4=0x1 & op16_8_4=0x2 & op16_7_1=0x1 & bow=0x0 & postRegIncrement) ... & REG_W_AS {
|
|
SP = SP - 0x2;
|
|
*:2 SP = inst_next;
|
|
PC = zext(REG_W_AS);
|
|
build postRegIncrement;
|
|
call [PC];
|
|
#Status bits are not affected
|
|
}
|
|
|
|
:CALL DirectAddr is ctx_haveext=0 & (op16_12_4=0x1 & op16_8_4=0x2 & op16_7_1=0x1 & reg16_0_4=0x0 & as=0x3 & bow=0x0 & postRegIncrement); DirectAddr {
|
|
SP = SP - 0x2;
|
|
*:2 SP = inst_next;
|
|
PC = &DirectAddr;
|
|
build postRegIncrement;
|
|
call DirectAddr;
|
|
#Status bits are not affected
|
|
}
|
|
|
|
|
|
|
|
###################################################################################
|
|
#
|
|
# RETI: Return from interrupt; pop SR then pop PC
|
|
# ------------------------------------------------------------------------------
|
|
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
# ------------------------------------------------------------------------------
|
|
# | 0 | 0 | 0 | 1 | 0 | 0 | 110 | 0 | 00 | 0000 |
|
|
:RETI is ctx_haveext=0 & op16_12_4=0x1 & op16_8_4=0x3 & op16_7_1=0x0 & as=0x0 & bow=0x0 & op16_0_4=0x0 & op16_4_4=0x0 {
|
|
@if REG_SIZE == "2"
|
|
SR = *:2 SP;
|
|
SP = SP + 0x2;
|
|
PC = *:2 SP;
|
|
@else
|
|
tmp:$(REG_SIZE) = zext(*:2 SP);
|
|
SR = zext(tmp[0,12]);
|
|
SP = SP + 0x2;
|
|
PC = zext(*:2 SP) | ((tmp & 0xF000) << 4);
|
|
@endif
|
|
SP = SP + 0x2;
|
|
return [PC];
|
|
#Status bits are restored from system stack
|
|
}
|
|
|
|
###################################################################################
|
|
#
|
|
# Conditional jump; PC = PC + 2*offset
|
|
#
|
|
# ------------------------------------------------------------------------------
|
|
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
# ------------------------------------------------------------------------------
|
|
# | 0 | 0 | 1 | condition | 10-bit signed offset |
|
|
# ------------------------------------------------------------------------------
|
|
###################################################################################
|
|
|
|
###################################################################################
|
|
#
|
|
# J^JumpCondition 10-bit_signed_offset
|
|
# ------------------------------------------------------------------------------
|
|
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
# ------------------------------------------------------------------------------
|
|
# | 0 | 0 | 1 | condition | 10-bit signed offset |
|
|
:J^JCND OFFSET_10BIT is ctx_haveext=0 & op16_13_3=0x1 & JCND & OFFSET_10BIT {
|
|
if (JCND) goto OFFSET_10BIT;
|
|
#Status bits are not affected
|
|
}
|
|
|
|
:JMP OFFSET_10BIT is ctx_haveext=0 & op16_13_3=0x1 & condition=0x7 & OFFSET_10BIT {
|
|
goto OFFSET_10BIT;
|
|
#Status bits are not affected
|
|
}
|
|
|
|
###################################################################################
|
|
#
|
|
# Two-operand arithmetic
|
|
#
|
|
# ------------------------------------------------------------------------------
|
|
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
# ------------------------------------------------------------------------------
|
|
# | opcode | source | Ad | B/W | As | destination |
|
|
# ------------------------------------------------------------------------------
|
|
###################################################################################
|
|
|
|
###################################################################################
|
|
#
|
|
# MOV: Move source to destination
|
|
# ------------------------------------------------------------------------------
|
|
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
# ------------------------------------------------------------------------------
|
|
# | 0 1 0 0 | source | Ad | B/W | As | destination |
|
|
#-----------------------
|
|
# Emulated instructions
|
|
#-----------------------
|
|
# Branch
|
|
:BR SRC_W_AS is ctx_haveext=0 & (op16_12_4=0x4 & bow=0x0 & ad=0x0 & dest_Direct16_0_4=0x0) ... & SRC_W_AS ... {
|
|
PC = zext(SRC_W_AS);
|
|
goto [PC];
|
|
#Status bits are not affected
|
|
}
|
|
|
|
# Branch to an immediate value
|
|
:BR DirectAddr is ctx_haveext=0 & (op16_12_4=0x4 & bow=0x0 & ad=0x0 & dest_Direct16_0_4=0x0 & src_Direct16_8_4=0x0 & as=0x3); DirectAddr {
|
|
PC = &DirectAddr;
|
|
goto DirectAddr;
|
|
#Status bits are not affected
|
|
}
|
|
|
|
# No operation
|
|
:NOP is ctx_haveext=0 & op16_12_4=0x4 & bow=0x0 & ad=0x0 & as=0x0 & dest_Direct16_0_4=0x3 & src_Direct16_8_4=0x3 & postIncrement {
|
|
#Status bits are not affected
|
|
build postIncrement;
|
|
}
|
|
|
|
# Pop word from stack
|
|
:POP^".W" DEST_W_AD is ctx_haveext=0 & (op16_12_4=0x4 & bow=0x0 & (ad=0x1 | dest_Direct16_0_4) & as=0x3 & src_Direct16_8_4=0x1 & tbl_wzero) ... & DEST_W_AD ... {
|
|
DEST_W_AD = *:2 SP;
|
|
build tbl_wzero;
|
|
SP = SP + 0x2;
|
|
#Status bits are not affected
|
|
}
|
|
|
|
# Pop byte from stack
|
|
:POP^".B" DEST_B_AD is ctx_haveext=0 & (op16_12_4=0x4 & bow=0x1 & (ad=0x1 | dest_Direct16_0_4) & as=0x3 & src_Direct16_8_4=0x1 & tbl_bzero) ... & DEST_B_AD ... {
|
|
DEST_B_AD = *:1 SP;
|
|
build tbl_bzero;
|
|
SP = SP + 0x2;
|
|
#Status bits are not affected
|
|
}
|
|
|
|
# Return from subroutine
|
|
:RET is ctx_haveext=0 & op16_12_4=0x4 & bow=0x0 & ad=0x0 & as=0x3 & dest_Direct16_0_4=0x0 & src_Direct16_8_4=0x1 {
|
|
PC = zext(*:2 SP);
|
|
SP = SP + 0x2;
|
|
return [PC];
|
|
#Status bits are not affected
|
|
}
|
|
|
|
#------------------
|
|
# SRC Word
|
|
#------------------
|
|
:MOV^".W" SRC_W_AS, DEST_W_AD is ctx_haveext=0 & (op16_12_4=0x4 & bow=0x0 & tbl_wzero & postIncrementStore) ... & SRC_W_AS ... & DEST_W_AD ... {
|
|
DEST_W_AD = SRC_W_AS;
|
|
build tbl_wzero;
|
|
#Status bits are not affected
|
|
build postIncrementStore;
|
|
}
|
|
|
|
|
|
#------------------
|
|
# SRC Byte
|
|
#------------------
|
|
:MOV^".B" SRC_B_AS, DEST_B_AD is ctx_haveext=0 & (op16_12_4=0x4 & bow=0x1 & tbl_bzero & postIncrementStore) ... & SRC_B_AS ... & DEST_B_AD ... {
|
|
DEST_B_AD = SRC_B_AS;
|
|
build tbl_bzero;
|
|
#Status bits are not affected
|
|
build postIncrementStore;
|
|
}
|
|
|
|
|
|
###################################################################################
|
|
#
|
|
# ADD: Add source to destination
|
|
# ------------------------------------------------------------------------------
|
|
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
# ------------------------------------------------------------------------------
|
|
# | 0 1 0 1 | source | Ad | B/W | As | destination |
|
|
#-----------------------
|
|
# Emulated instructions
|
|
#-----------------------
|
|
# Increment word
|
|
:INC^".W" DEST_W_AD is ctx_haveext=0 & (op16_12_4=0x5 & as=0x1 & src_Direct16_8_4=0x3 & bow=0x0 & tbl_wzero & postIncrementStore) ... & DEST_W_AD ... {
|
|
# Operation Flags...
|
|
$(CARRY) = carry(DEST_W_AD,1); # C Flag
|
|
$(OVERFLOW) = scarry(DEST_W_AD,1); # V Flag
|
|
# Operation...
|
|
DEST_W_AD = DEST_W_AD + 0x1;
|
|
build tbl_wzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_W_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_W_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
# Increment byte
|
|
:INC^".B" DEST_B_AD is ctx_haveext=0 & (op16_12_4=0x5 & as=0x1 & src_Direct16_8_4=0x3 & bow=0x1 & tbl_bzero & postIncrementStore) ... & DEST_B_AD ... {
|
|
# Operation Flags...
|
|
$(CARRY) = carry(DEST_B_AD,1); # C Flag
|
|
$(OVERFLOW) = scarry(DEST_B_AD,1); # V Flag
|
|
# Operation...
|
|
DEST_B_AD = DEST_B_AD + 0x1;
|
|
build tbl_bzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_B_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_B_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
# Double increment word
|
|
:INCD^".W" DEST_W_AD is ctx_haveext=0 & (op16_12_4=0x5 & as=0x2 & src_Direct16_8_4=0x3 & bow=0x0 & tbl_wzero & postIncrementStore) ... & DEST_W_AD ... {
|
|
# Operation Flags...
|
|
$(CARRY) = carry(DEST_W_AD,2); # C Flag
|
|
$(OVERFLOW) = scarry(DEST_W_AD,2); # V Flag
|
|
# Operation...
|
|
DEST_W_AD = DEST_W_AD + 0x2;
|
|
build tbl_wzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_W_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_W_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
# Double increment byte
|
|
:INCD^".B" DEST_B_AD is ctx_haveext=0 & (op16_12_4=0x5 & as=0x2 & src_Direct16_8_4=0x3 & bow=0x1 & tbl_bzero & postIncrementStore) ... & DEST_B_AD ... {
|
|
# Operation Flags...
|
|
$(CARRY) = carry(DEST_B_AD,2); # C Flag
|
|
$(OVERFLOW) = scarry(DEST_B_AD,2); # V Flag
|
|
# Operation...
|
|
DEST_B_AD = DEST_B_AD + 0x2;
|
|
build tbl_bzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_B_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_B_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
# Rotate left arithmetic (left shift once) word
|
|
:RLA^".W" DEST_W_AD is ctx_haveext=0 & (op16_12_4=0x5 & as=0x0 & ad=0x0 & src_Direct16_8_4=dest_Direct16_0_4 & bow=0x0 & tbl_wzero & postIncrementStore) ... & DEST_W_AD ... {
|
|
# Operation Flags...
|
|
$(CARRY) = carry(DEST_W_AD, DEST_W_AD); # C Flag
|
|
$(OVERFLOW) = scarry(DEST_W_AD, DEST_W_AD); # V Flag
|
|
# Operation...
|
|
DEST_W_AD = DEST_W_AD + DEST_W_AD;
|
|
build tbl_wzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_W_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_W_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
# Rotate left arithmetic (left shift once) byte
|
|
:RLA^".B" DEST_B_AD is ctx_haveext=0 & (op16_12_4=0x5 & as=0x0 & ad=0x0 & src_Direct16_8_4=dest_Direct16_0_4 & bow=0x1 & tbl_bzero & postIncrementStore) ... & DEST_B_AD ... {
|
|
# Operation Flags...
|
|
$(CARRY) = carry(DEST_B_AD, DEST_B_AD); # C Flag
|
|
$(OVERFLOW) = scarry(DEST_B_AD, DEST_B_AD); # V Flag
|
|
# Operation...
|
|
DEST_B_AD = DEST_B_AD + DEST_B_AD;
|
|
build tbl_bzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_B_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_B_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
#------------------
|
|
# 16 bit SRC Word
|
|
#------------------
|
|
:ADD^".W" SRC_W_AS, DEST_W_AD is ctx_haveext=0 & (op16_12_4=0x5 & bow=0x0 & tbl_wzero & postIncrementStore) ... & SRC_W_AS ... & DEST_W_AD ... {
|
|
# Operation Flags...
|
|
$(CARRY) = carry(SRC_W_AS, DEST_W_AD); # C Flag
|
|
$(OVERFLOW) = scarry(SRC_W_AS, DEST_W_AD); # V Flag
|
|
# Operation...
|
|
DEST_W_AD = SRC_W_AS + DEST_W_AD;
|
|
build tbl_wzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_W_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_W_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
|
|
#------------------
|
|
# 16 bit SRC Byte
|
|
#------------------
|
|
:ADD^".B" SRC_B_AS, DEST_B_AD is ctx_haveext=0 & (op16_12_4=0x5 & bow=0x1 & tbl_bzero & postIncrementStore) ... & SRC_B_AS ... & DEST_B_AD ... {
|
|
# Operation Flags...
|
|
$(CARRY) = carry(SRC_B_AS, DEST_B_AD); # C Flag
|
|
$(OVERFLOW) = scarry(SRC_B_AS, DEST_B_AD); # V Flag
|
|
# Operation...
|
|
DEST_B_AD = SRC_B_AS + DEST_B_AD;
|
|
build tbl_bzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_B_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_B_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
|
|
###################################################################################
|
|
#
|
|
# ADDC: Add source and carry to destination
|
|
# ------------------------------------------------------------------------------
|
|
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
# ------------------------------------------------------------------------------
|
|
# | 0 1 1 0 | source | Ad | B/W | As | destination |
|
|
#-----------------------
|
|
# Emulated instructions
|
|
#-----------------------
|
|
# Add carry to word
|
|
:ADC^".W" DEST_W_AD is ctx_haveext=0 & (op16_12_4=0x6 & as=0x0 & src_Direct16_8_4=0x3 & bow=0x0 & tbl_wzero & postIncrementStore) ... & DEST_W_AD ... {
|
|
# Operation Flags...
|
|
tmp_carry:1 = carry(DEST_W_AD,zext($(CARRY))); #C Flag
|
|
$(OVERFLOW) = scarry(DEST_W_AD, zext($(CARRY))); #V Flag
|
|
# Operation...
|
|
DEST_W_AD = DEST_W_AD + zext($(CARRY));
|
|
build tbl_wzero;
|
|
# Result Flags...
|
|
$(CARRY) = tmp_carry;
|
|
$(SIGN) = (DEST_W_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_W_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
# Add carry to byte
|
|
:ADC^".B" DEST_B_AD is ctx_haveext=0 & (op16_12_4=0x6 & as=0x0 & src_Direct16_8_4=0x3 & bow=0x1 & tbl_bzero & postIncrementStore) ... & DEST_B_AD ... {
|
|
# Operation Flags...
|
|
tmp_carry:1 = carry(DEST_B_AD,$(CARRY)); #C Flag
|
|
$(OVERFLOW) = scarry(DEST_B_AD,$(CARRY)); #V Flag
|
|
# Operation...
|
|
DEST_B_AD = DEST_B_AD + $(CARRY);
|
|
build tbl_bzero;
|
|
# Result Flags...
|
|
$(CARRY) = tmp_carry;
|
|
$(SIGN) = (DEST_B_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_B_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
# Rotate word left through carry
|
|
:RLC^".W" DEST_W_AD is ctx_haveext=0 & (op16_12_4=0x6 & as=0x0 & ad=0x0 & src_Direct16_8_4=dest_Direct16_0_4 & bow=0x0 & tbl_wzero & postIncrementStore) ... & DEST_W_AD ... {
|
|
# Operation Flags...
|
|
tmp_carry:1 = (carry(DEST_W_AD,zext($(CARRY))) || carry(DEST_W_AD,DEST_W_AD + zext($(CARRY)))); #C Flag
|
|
$(OVERFLOW) = (scarry(DEST_W_AD,zext($(CARRY))) || scarry(DEST_W_AD,DEST_W_AD + zext($(CARRY)))); #V Flag
|
|
# Operation...
|
|
DEST_W_AD = DEST_W_AD + DEST_W_AD + zext($(CARRY));
|
|
build tbl_wzero;
|
|
# Result Flags...
|
|
$(CARRY) = tmp_carry;
|
|
$(SIGN) = (DEST_W_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_W_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
# Rotate byte left through carry
|
|
:RLC^".B" DEST_B_AD is ctx_haveext=0 & (op16_12_4=0x6 & as=0x0 & ad=0x0 & src_Direct16_8_4=dest_Direct16_0_4 & bow=0x1 & tbl_bzero & postIncrementStore) ... & DEST_B_AD ... {
|
|
# Operation Flags...
|
|
tmp_carry:1 = (carry(DEST_B_AD, $(CARRY)) || carry(DEST_B_AD,DEST_B_AD + $(CARRY))); #C Flag
|
|
$(OVERFLOW) = (scarry(DEST_B_AD, $(CARRY)) || scarry(DEST_B_AD,DEST_B_AD + $(CARRY))); #V Flag
|
|
# Operation...
|
|
DEST_B_AD = DEST_B_AD + DEST_B_AD + $(CARRY);
|
|
build tbl_bzero;
|
|
# Result Flags...
|
|
$(CARRY) = tmp_carry;
|
|
$(SIGN) = (DEST_B_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_B_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
#------------------
|
|
# 16 bit SRC Word
|
|
#------------------
|
|
:ADDC^".W" SRC_W_AS, DEST_W_AD is ctx_haveext=0 & (op16_12_4=0x6 & bow=0x0 & tbl_wzero & postIncrementStore) ... & SRC_W_AS ... & DEST_W_AD ... {
|
|
# Operation Flags...
|
|
tmp_carry:1 = (carry(SRC_W_AS,zext($(CARRY))) || carry(DEST_W_AD,SRC_W_AS + zext($(CARRY)))); #C Flag
|
|
$(OVERFLOW) = (scarry(SRC_W_AS,zext($(CARRY))) || scarry(DEST_W_AD,SRC_W_AS + zext($(CARRY)))); #V Flag
|
|
# Operation...
|
|
DEST_W_AD = SRC_W_AS + DEST_W_AD + zext($(CARRY));
|
|
build tbl_wzero;
|
|
# Result Flags...
|
|
$(CARRY) = tmp_carry;
|
|
$(SIGN) = (DEST_W_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_W_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
|
|
#------------------
|
|
# 16 bit SRC Byte
|
|
#------------------
|
|
:ADDC^".B" SRC_B_AS, DEST_B_AD is ctx_haveext=0 & (op16_12_4=0x6 & bow=0x1 & tbl_bzero & postIncrementStore) ... & SRC_B_AS ... & DEST_B_AD ... {
|
|
# Operation Flags...
|
|
tmp_carry:1 = (carry(SRC_B_AS, $(CARRY)) || carry(DEST_B_AD,SRC_B_AS + $(CARRY))); #C Flag
|
|
$(OVERFLOW) = (scarry(SRC_B_AS, $(CARRY)) || scarry(DEST_B_AD,SRC_B_AS + $(CARRY))); #V Flag
|
|
# Operation...
|
|
DEST_B_AD = SRC_B_AS + DEST_B_AD + $(CARRY);
|
|
build tbl_bzero;
|
|
# Result Flags...
|
|
$(CARRY) = tmp_carry;
|
|
$(SIGN) = (DEST_B_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_B_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
|
|
###################################################################################
|
|
#
|
|
# SUBC: Subtract source from destination (with carry)
|
|
# ------------------------------------------------------------------------------
|
|
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
# ------------------------------------------------------------------------------
|
|
# | 0 1 1 1 | source | Ad | B/W | As | destination |
|
|
#-----------------------
|
|
# Emulated instructions
|
|
#-----------------------
|
|
# Subtract borrow from word
|
|
:SBC^".W" DEST_W_AD is ctx_haveext=0 & (op16_12_4=0x7 & as=0x0 & src_Direct16_8_4=0x3 & bow=0x0 & tbl_wzero & postIncrementStore) ... & DEST_W_AD ... {
|
|
# Operation Flags...
|
|
brw:2 = 1 - zext( $(CARRY) );
|
|
$(CARRY) = (brw <= DEST_W_AD); # Carry flag is NOT set if there is a borrow
|
|
$(OVERFLOW) = sborrow(DEST_W_AD, brw);
|
|
# Operation...
|
|
DEST_W_AD = DEST_W_AD - brw;
|
|
build tbl_wzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_W_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_W_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
# Subtract borrow from byte
|
|
:SBC^".B" DEST_B_AD is ctx_haveext=0 & (op16_12_4=0x7 & as=0x0 & src_Direct16_8_4=0x3 & bow=0x1 & tbl_bzero & postIncrementStore) ... & DEST_B_AD ... {
|
|
# Operation Flags...
|
|
brw:1 = 1 - $(CARRY);
|
|
$(CARRY) = (brw <= DEST_B_AD); # Carry flag is NOT set if there is a borrow
|
|
$(OVERFLOW) = sborrow(DEST_B_AD, brw);
|
|
# Operation...
|
|
DEST_B_AD = DEST_B_AD - brw;
|
|
build tbl_bzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_B_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_B_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
#------------------
|
|
# 16 bit SRC Word
|
|
#------------------
|
|
:SUBC^".W" SRC_W_AS, DEST_W_AD is ctx_haveext=0 & (op16_12_4=0x7 & bow=0x0 & tbl_wzero & postIncrementStore) ... & SRC_W_AS ... & DEST_W_AD ... {
|
|
# Operation Flags...
|
|
brw:2 = 1 - zext( $(CARRY) );
|
|
$(CARRY) = ((brw + SRC_W_AS) <= DEST_W_AD); # Carry flag is NOT set if there is a borrow
|
|
$(OVERFLOW) = sborrow(DEST_W_AD, SRC_W_AS + brw);
|
|
# Operation...
|
|
DEST_W_AD = DEST_W_AD - SRC_W_AS - brw;
|
|
build tbl_wzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_W_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_W_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
|
|
#------------------
|
|
# 16 bit SRC Byte
|
|
#------------------
|
|
:SUBC^".B" SRC_B_AS, DEST_B_AD is ctx_haveext=0 & (op16_12_4=0x7 & bow=0x1 & tbl_bzero & postIncrementStore) ... & SRC_B_AS ... & DEST_B_AD ... {
|
|
# Operation Flags...
|
|
brw:1 = 1 - $(CARRY);
|
|
$(CARRY) = ((brw + SRC_B_AS) <= DEST_B_AD); # Carry flag is NOT set if there is a borrow
|
|
$(OVERFLOW) = sborrow(DEST_B_AD, SRC_B_AS + brw);
|
|
# Operation...
|
|
DEST_B_AD = DEST_B_AD - SRC_B_AS - brw;
|
|
build tbl_bzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_B_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_B_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
|
|
###################################################################################
|
|
#
|
|
# SUB: Subtract source from destination
|
|
# ------------------------------------------------------------------------------
|
|
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
# ------------------------------------------------------------------------------
|
|
# | 1 0 0 0 | source | Ad | B/W | As | destination |
|
|
#-----------------------
|
|
# Emulated instructions
|
|
#-----------------------
|
|
# Decrement word
|
|
:DEC^".W" DEST_W_AD is ctx_haveext=0 & (op16_12_4=0x8 & as=0x1 & src_Direct16_8_4=0x3 & bow=0x0 & tbl_wzero & postIncrementStore) ... & DEST_W_AD ... {
|
|
# Operation Flags...
|
|
$(CARRY) = (0x0 == DEST_W_AD); # C Flag
|
|
$(OVERFLOW) = (0x8000 == DEST_W_AD); # V Flag
|
|
# Operation...
|
|
DEST_W_AD = DEST_W_AD - 0x1;
|
|
build tbl_wzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_W_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_W_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
# Decrement byte
|
|
:DEC^".B" DEST_B_AD is ctx_haveext=0 & (op16_12_4=0x8 & as=0x1 & src_Direct16_8_4=0x3 & bow=0x1 & tbl_bzero & postIncrementStore) ... & DEST_B_AD ... {
|
|
# Operation Flags...
|
|
$(CARRY) = (0x0 == DEST_B_AD); # C Flag
|
|
$(OVERFLOW) = (0x80 == DEST_B_AD); # V Flag
|
|
# Operation...
|
|
DEST_B_AD = DEST_B_AD - 0x1;
|
|
build tbl_bzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_B_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_B_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
# Double decrement word
|
|
:DECD^".W" DEST_W_AD is ctx_haveext=0 & (op16_12_4=0x8 & as=0x2 & src_Direct16_8_4=0x3 & bow=0x0 & tbl_wzero & postIncrementStore) ... & DEST_W_AD ... {
|
|
# Operation Flags...
|
|
$(CARRY) = ((0x0 == DEST_W_AD) || (0x1 == DEST_W_AD)); # C Flag
|
|
$(OVERFLOW) = ((0x8000 == DEST_W_AD) || (0x8001 == DEST_W_AD)); # V Flag
|
|
# Operation...
|
|
DEST_W_AD = DEST_W_AD - 0x2;
|
|
build tbl_wzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_W_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_W_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
# Double decrement byte
|
|
:DECD^".B" DEST_B_AD is ctx_haveext=0 & (op16_12_4=0x8 & as=0x2 & src_Direct16_8_4=0x3 & bow=0x1 & tbl_bzero & postIncrementStore) ... & DEST_B_AD ... {
|
|
# Operation Flags...
|
|
$(CARRY) = ((0x0 == DEST_B_AD) || (0x1 == DEST_B_AD)); # C Flag
|
|
$(OVERFLOW) = ((0x80 == DEST_B_AD) || (0x81 == DEST_B_AD)); # V Flag
|
|
# Operation...
|
|
DEST_B_AD = DEST_B_AD - 0x2;
|
|
build tbl_bzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_B_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_B_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
#------------------
|
|
# 16 bit SRC Word
|
|
#------------------
|
|
:SUB^".W" SRC_W_AS, DEST_W_AD is ctx_haveext=0 & (op16_12_4=0x8 & bow=0x0 & tbl_wzero & postIncrementStore) ... & SRC_W_AS ... & DEST_W_AD ... {
|
|
# Operation Flags...
|
|
$(CARRY) = (SRC_W_AS <= DEST_W_AD); # Carry is NOT set if there is a borrow
|
|
$(OVERFLOW) = sborrow(DEST_W_AD, SRC_W_AS); # V Flag
|
|
# Operation...
|
|
DEST_W_AD = DEST_W_AD - SRC_W_AS;
|
|
build tbl_wzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_W_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_W_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
|
|
#------------------
|
|
# 16 bit SRC Byte
|
|
#------------------
|
|
:SUB^".B" SRC_B_AS, DEST_B_AD is ctx_haveext=0 & (op16_12_4=0x8 & bow=0x1 & tbl_bzero & postIncrementStore) ... & SRC_B_AS ... & DEST_B_AD ... {
|
|
# Operation Flags...
|
|
$(CARRY) = (SRC_B_AS <= DEST_B_AD); # Carry is NOT set if there is a borrow
|
|
$(OVERFLOW) = sborrow(DEST_B_AD, SRC_B_AS); # V Flag
|
|
# Operation...
|
|
DEST_B_AD = DEST_B_AD - SRC_B_AS;
|
|
build tbl_bzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_B_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_B_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
|
|
###################################################################################
|
|
#
|
|
# CMP: Compare (pretend to subtract) source from destination
|
|
# ------------------------------------------------------------------------------
|
|
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
# ------------------------------------------------------------------------------
|
|
# | 1 0 0 1 | source | Ad | B/W | As | destination |
|
|
#-----------------------
|
|
# Emulated instructions
|
|
#-----------------------
|
|
# Test word
|
|
:TST^".W" DEST_W_AD is ctx_haveext=0 & (op16_12_4=0x9 & as=0x0 & src_Direct16_8_4=0x3 & bow=0x0 & postIncrement) ... & DEST_W_AD ... {
|
|
# Operation Flags...
|
|
$(CARRY) = 1; # Carry is NOT set if there is a borrow
|
|
$(OVERFLOW) = 0; # V Flag
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_W_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_W_AD == 0x0); # Z Flag
|
|
build postIncrement;
|
|
}
|
|
|
|
# Test byte
|
|
:TST^".B" DEST_B_AD is ctx_haveext=0 & (op16_12_4=0x9 & as=0x0 & src_Direct16_8_4=0x3 & bow=0x1 & postIncrement) ... & DEST_B_AD ... {
|
|
# Operation Flags...
|
|
$(CARRY) = 1; # Carry is NOT set if there is a borrow
|
|
$(OVERFLOW) = 0; # V Flag
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_B_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_B_AD == 0x0); # Z Flag
|
|
build postIncrement;
|
|
}
|
|
|
|
#------------------
|
|
# 16 bit SRC Word
|
|
#------------------
|
|
:CMP^".W" SRC_W_AS, DEST_W_AD is ctx_haveext=0 & (op16_12_4=0x9 & bow=0x0 & postIncrement) ... & SRC_W_AS ... & DEST_W_AD ... {
|
|
# Operation Flags...
|
|
$(CARRY) = (SRC_W_AS <= DEST_W_AD); # Carry is NOT set if there is a borrow
|
|
$(OVERFLOW) = sborrow(DEST_W_AD, SRC_W_AS); # V Flag
|
|
# Operation...
|
|
result:2 = (DEST_W_AD - SRC_W_AS);
|
|
# Result Flags...
|
|
$(SIGN) = (result s< 0x0); # S Flag
|
|
$(ZERO) = (result == 0x0); # Z Flag
|
|
build postIncrement;
|
|
}
|
|
|
|
|
|
#------------------
|
|
# 16 bit SRC Byte
|
|
#------------------
|
|
:CMP^".B" SRC_B_AS, DEST_B_AD is ctx_haveext=0 & (op16_12_4=0x9 & bow=0x1 & postIncrement) ... & SRC_B_AS ... & DEST_B_AD ... {
|
|
# Operation Flags...
|
|
$(CARRY) = (SRC_B_AS <= DEST_B_AD); # Carry is NOT set if there is a borrow
|
|
$(OVERFLOW) = sborrow(DEST_B_AD, SRC_B_AS); # V Flag
|
|
# Operation...
|
|
result:1 = (DEST_B_AD - SRC_B_AS);
|
|
# Result Flags...
|
|
$(SIGN) = (result s< 0x0); # S Flag
|
|
$(ZERO) = (result == 0x0); # Z Flag
|
|
build postIncrement;
|
|
}
|
|
|
|
|
|
###################################################################################
|
|
#
|
|
# DADD: Decimal add source to destination (with carry)
|
|
# ------------------------------------------------------------------------------
|
|
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
# ------------------------------------------------------------------------------
|
|
# | 1 0 1 0 | source | Ad | B/W | As | destination |
|
|
#----------------------------------------------------------------------------------------------------------------
|
|
# These decimal add instructions appear to lack supporting BCD p-code operations to handle carries and overflows.
|
|
#----------------------------------------------------------------------------------------------------------------
|
|
#-----------------------
|
|
# Emulated instructions
|
|
#-----------------------
|
|
# Decimal add carry to word
|
|
:DADC^".W" DEST_W_AD is ctx_haveext=0 & (op16_12_4=0xA & as=0x0 & src_Direct16_8_4=0x3 & bow=0x0 & tbl_wzero & postIncrementStore) ... & DEST_W_AD ... {
|
|
# Operation...
|
|
DEST_W_AD = bcd_add($(CARRY) ,DEST_W_AD);
|
|
build tbl_wzero;
|
|
# Operation Flags...
|
|
$(CARRY) = 0; # Don't currently have BCD overflow op
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_W_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_W_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
# Decimal add carry to byte
|
|
:DADC^".B" DEST_B_AD is ctx_haveext=0 & (op16_12_4=0xA & as=0x0 & src_Direct16_8_4=0x3 & bow=0x1 & tbl_bzero & postIncrementStore) ... & DEST_B_AD ... {
|
|
# Operation...
|
|
DEST_B_AD = bcd_add($(CARRY),DEST_B_AD);
|
|
build tbl_bzero;
|
|
# Operation Flags...
|
|
$(CARRY) = 0; # This should be overflow
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_B_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_B_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
#------------------
|
|
# 16 bit SRC Word
|
|
#------------------
|
|
:DADD^".W" SRC_W_AS, DEST_W_AD is ctx_haveext=0 & (op16_12_4=0xA & bow=0x0 & tbl_wzero & postIncrementStore) ... & SRC_W_AS ... & DEST_W_AD ... {
|
|
# Operation Flags...
|
|
$(CARRY) = 0; # Don't currently have BCD overflow op
|
|
# Operation...
|
|
DEST_W_AD = bcd_add(SRC_W_AS ,DEST_W_AD);
|
|
build tbl_wzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_W_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_W_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
#------------------
|
|
# 16 bit SRC Byte
|
|
#------------------
|
|
:DADD^".B" SRC_B_AS, DEST_B_AD is ctx_haveext=0 & (op16_12_4=0xA & bow=0x1 & tbl_bzero & postIncrementStore) ... & SRC_B_AS ... & DEST_B_AD ... {
|
|
# Operation Flags...
|
|
$(CARRY) = 0; # This should be overflow
|
|
# Operation...
|
|
DEST_B_AD = bcd_add(SRC_B_AS,DEST_B_AD);
|
|
build tbl_bzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_B_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_B_AD == 0x0); # Z Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
|
|
###################################################################################
|
|
#
|
|
# BIT: Test bits of source AND destination
|
|
# ------------------------------------------------------------------------------
|
|
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
# ------------------------------------------------------------------------------
|
|
# | 1 0 1 1 | source | Ad | B/W | As | destination |
|
|
#------------------
|
|
# 16 bit SRC Word
|
|
#------------------
|
|
:BIT^".W" SRC_W_AS, DEST_W_AD is ctx_haveext=0 & (op16_12_4=0xB & bow=0x0 & postIncrement) ... & SRC_W_AS ... & DEST_W_AD ... {
|
|
# Operation Flags...
|
|
$(OVERFLOW) = 0x0; # V Flag (reset)
|
|
# Operation...
|
|
result:2 = DEST_W_AD & SRC_W_AS;
|
|
# Result Flags...
|
|
$(CARRY) = (result != 0x0); # C Flag
|
|
$(SIGN) = (result s< 0x0); # S Flag
|
|
$(ZERO) = (result == 0x0); # Z Flag
|
|
build postIncrement;
|
|
}
|
|
|
|
|
|
#------------------
|
|
# 16 bit SRC Byte
|
|
#------------------
|
|
:BIT^".B" SRC_B_AS, DEST_B_AD is ctx_haveext=0 & (op16_12_4=0xB & bow=0x1 & postIncrement) ... & SRC_B_AS ... & DEST_B_AD ... {
|
|
# Operation Flags...
|
|
$(OVERFLOW) = 0x0; # V Flag (reset)
|
|
# Operation...
|
|
result:1 = DEST_B_AD & SRC_B_AS;
|
|
# Result Flags...
|
|
$(CARRY) = (result != 0x0); # C Flag
|
|
$(SIGN) = (result s< 0x0); # S Flag
|
|
$(ZERO) = (result == 0x0); # Z Flag
|
|
build postIncrement;
|
|
}
|
|
|
|
|
|
###################################################################################
|
|
#
|
|
# BIC: Bit clear (dest &= ~src)
|
|
# ------------------------------------------------------------------------------
|
|
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
# ------------------------------------------------------------------------------
|
|
# | 1 1 0 0 | source | Ad | B/W | As | destination |
|
|
#-----------------------
|
|
# Emulated instructions
|
|
#-----------------------
|
|
# Clear carry bit
|
|
:CLRC is ctx_haveext=0 & op16_12_4=0xC & as=0x1 & src_Direct16_8_4=0x3 & ad=0x0 & dest_Direct16_0_4=0x2 & bow=0x0 & postIncrementStore {
|
|
$(CARRY) = 0;
|
|
build postIncrementStore;
|
|
}
|
|
|
|
# Clear sign bit
|
|
:CLRN is ctx_haveext=0 & op16_12_4=0xC & as=0x2 & src_Direct16_8_4=0x2 & ad=0x0 & dest_Direct16_0_4=0x2 & bow=0x0 & postIncrementStore {
|
|
$(SIGN) = 0;
|
|
build postIncrementStore;
|
|
}
|
|
|
|
# Clear zero bit
|
|
:CLRZ is ctx_haveext=0 & op16_12_4=0xC & as=0x2 & src_Direct16_8_4=0x3 & ad=0x0 & dest_Direct16_0_4=0x2 & bow=0x0 & postIncrementStore {
|
|
$(ZERO) = 0;
|
|
build postIncrementStore;
|
|
}
|
|
|
|
# Disable interrupts
|
|
:DINT is ctx_haveext=0 & op16_12_4=0xC & as=0x3 & src_Direct16_8_4=0x2 & ad=0x0 & dest_Direct16_0_4=0x2 & postIncrementStore {
|
|
$(GIE) = 0;
|
|
build postIncrementStore;
|
|
}
|
|
|
|
#------------------
|
|
# 16 bit SRC Word
|
|
#------------------
|
|
:BIC^".W" SRC_W_AS, DEST_W_AD is ctx_haveext=0 & (op16_12_4=0xC & bow=0x0 & tbl_wzero & postIncrementStore) ... & SRC_W_AS ... & DEST_W_AD ... {
|
|
DEST_W_AD = (~SRC_W_AS) & DEST_W_AD;
|
|
build tbl_wzero;
|
|
#Status bits are not affected
|
|
build postIncrementStore;
|
|
}
|
|
|
|
|
|
#------------------
|
|
# 16 bit SRC Byte
|
|
#------------------
|
|
:BIC^".B" SRC_B_AS, DEST_B_AD is ctx_haveext=0 & (op16_12_4=0xC & bow=0x1 & tbl_bzero & postIncrementStore) ... & SRC_B_AS ... & DEST_B_AD ... {
|
|
DEST_B_AD = (~SRC_B_AS) & DEST_B_AD;
|
|
build tbl_bzero;
|
|
#Status bits are not affected
|
|
build postIncrementStore;
|
|
}
|
|
|
|
|
|
###################################################################################
|
|
#
|
|
# BIS: Bit set (logical OR)
|
|
# ------------------------------------------------------------------------------
|
|
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
# ------------------------------------------------------------------------------
|
|
# | 1 1 0 1 | source | Ad | B/W | As | destination |
|
|
#-----------------------
|
|
# Emulated instructions
|
|
#-----------------------
|
|
# Enable interrupts
|
|
:EINT is ctx_haveext=0 & op16_12_4=0xD & as=0x3 & src_Direct16_8_4=0x2 & ad=0x0 & dest_Direct16_0_4=0x2 & postIncrementStore {
|
|
$(GIE) = 1;
|
|
build postIncrementStore;
|
|
}
|
|
|
|
# Set carry bit
|
|
:SETC is ctx_haveext=0 & (op16_12_4=0xD & as=0x1 & src_Direct16_8_4=0x3 & ad=0x0 & dest_Direct16_0_4=0x2 & bow=0x0 & postIncrementStore) {
|
|
$(CARRY) = 1;
|
|
build postIncrementStore;
|
|
}
|
|
|
|
# Set sign bit
|
|
:SETN is ctx_haveext=0 & (op16_12_4=0xD & as=0x2 & src_Direct16_8_4=0x2 & ad=0x0 & dest_Direct16_0_4=0x2 & bow=0x0 & postIncrementStore) {
|
|
$(SIGN) = 1;
|
|
build postIncrementStore;
|
|
}
|
|
|
|
# Set zero bit
|
|
:SETZ is ctx_haveext=0 & (op16_12_4=0xD & as=0x2 & src_Direct16_8_4=0x3 & ad=0x0 & dest_Direct16_0_4=0x2 & bow=0x0 & postIncrementStore) {
|
|
$(ZERO) = 1;
|
|
build postIncrementStore;
|
|
}
|
|
|
|
#------------------
|
|
# 16 bit SRC Word
|
|
#------------------
|
|
:BIS^".W" SRC_W_AS, DEST_W_AD is ctx_haveext=0 & (op16_12_4=0xD & bow=0x0 & tbl_wzero & postIncrementStore) ... & SRC_W_AS ... & DEST_W_AD ... {
|
|
DEST_W_AD = SRC_W_AS | DEST_W_AD;
|
|
build tbl_wzero;
|
|
#Status bits are not affected
|
|
build postIncrementStore;
|
|
}
|
|
|
|
|
|
#------------------
|
|
# 16 bit SRC Byte
|
|
#------------------
|
|
:BIS^".B" SRC_B_AS, DEST_B_AD is ctx_haveext=0 & (op16_12_4=0xD & bow=0x1 & tbl_bzero & postIncrementStore) ... & SRC_B_AS ... & DEST_B_AD ... {
|
|
DEST_B_AD = SRC_B_AS | DEST_B_AD;
|
|
build tbl_bzero;
|
|
#Status bits are not affected
|
|
build postIncrementStore;
|
|
}
|
|
|
|
|
|
|
|
###################################################################################
|
|
#
|
|
# XOR: Exclusive or source with destination
|
|
# ------------------------------------------------------------------------------
|
|
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
# ------------------------------------------------------------------------------
|
|
# | 1 1 1 0 | source | Ad | B/W | As | destination |
|
|
#-----------------------
|
|
# Emulated instructions
|
|
#-----------------------
|
|
# Invert word
|
|
:INV^".W" DEST_W_AD is ctx_haveext=0 & (op16_12_4=0xE & as=0x3 & src_Direct16_8_4=0x3 & bow=0x0 & tbl_wzero & postIncrementStore) ... & DEST_W_AD ... {
|
|
# Operation Flags...
|
|
$(OVERFLOW) = (DEST_W_AD s< 0x0); # V Flag
|
|
# Operation...
|
|
DEST_W_AD = DEST_W_AD ^ 0xFFFF;
|
|
build tbl_wzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_W_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_W_AD == 0x0); # Z Flag
|
|
$(CARRY) = (DEST_W_AD != 0x0); # C Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
# Invert byte
|
|
:INV^".B" DEST_B_AD is ctx_haveext=0 & (op16_12_4=0xE & as=0x3 & src_Direct16_8_4=0x3 & bow=0x1 & tbl_bzero & postIncrementStore) ... & DEST_B_AD ... {
|
|
# Operation Flags...
|
|
$(OVERFLOW) = (DEST_B_AD s< 0x0); # V Flag
|
|
# Operation...
|
|
DEST_B_AD = DEST_B_AD ^ 0xFF;
|
|
build tbl_bzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_B_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_B_AD == 0x0); # Z Flag
|
|
$(CARRY) = (DEST_B_AD != 0x0); # C Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
#------------------
|
|
# 16 bit SRC Word
|
|
#------------------
|
|
:XOR^".W" SRC_W_AS, DEST_W_AD is ctx_haveext=0 & (op16_12_4=0xE & bow=0x0 & tbl_wzero & postIncrementStore) ... & SRC_W_AS ... & DEST_W_AD ... {
|
|
# Operation Flags...
|
|
$(OVERFLOW) = ((DEST_W_AD s< 0x0) && (SRC_W_AS s< 0x0)) ; # V Flag
|
|
# Operation...
|
|
DEST_W_AD = DEST_W_AD ^ SRC_W_AS;
|
|
build tbl_wzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_W_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_W_AD == 0x0); # Z Flag
|
|
$(CARRY) = (DEST_W_AD != 0x0); # C Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
#------------------
|
|
# 16 bit SRC Byte
|
|
#------------------
|
|
:XOR^".B" SRC_B_AS, DEST_B_AD is ctx_haveext=0 & (op16_12_4=0xE & bow=0x1 & tbl_bzero & postIncrementStore) ... & SRC_B_AS ... & DEST_B_AD ... {
|
|
# Operation Flags...
|
|
$(OVERFLOW) = ((DEST_B_AD s< 0x0) && (SRC_B_AS s< 0x0)) ; # V Flag
|
|
# Operation...
|
|
DEST_B_AD = DEST_B_AD ^ SRC_B_AS;
|
|
build tbl_bzero;
|
|
# Result Flags...
|
|
$(SIGN) = (DEST_B_AD s< 0x0); # S Flag
|
|
$(ZERO) = (DEST_B_AD == 0x0); # Z Flag
|
|
$(CARRY) = (DEST_B_AD != 0x0); # C Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
|
|
###################################################################################
|
|
#
|
|
# AND: Logical AND source with destination (dest &= src)
|
|
# ------------------------------------------------------------------------------
|
|
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
# ------------------------------------------------------------------------------
|
|
# | 1 1 1 1 | source | Ad | B/W | As | destination |
|
|
#------------------
|
|
# 16 bit SRC Word
|
|
#------------------
|
|
:AND^".W" SRC_W_AS, DEST_W_AD is ctx_haveext=0 & (op16_12_4=0xF & bow=0x0 & tbl_wzero & postIncrementStore) ... & SRC_W_AS ... & DEST_W_AD ... {
|
|
# Operation Flags...
|
|
$(OVERFLOW) = 0x0; # V Flag
|
|
# Operation...
|
|
result:2 = DEST_W_AD & SRC_W_AS;
|
|
DEST_W_AD = result;
|
|
build tbl_wzero;
|
|
# Result Flags...
|
|
$(SIGN) = (result s< 0x0); # S Flag
|
|
$(ZERO) = (result == 0x0); # Z Flag
|
|
$(CARRY) = (result != 0x0); # C Flag
|
|
build postIncrementStore;
|
|
}
|
|
|
|
|
|
#------------------
|
|
# 16 bit SRC Byte
|
|
#------------------
|
|
:AND^".B" SRC_B_AS, DEST_B_AD is ctx_haveext=0 & (op16_12_4=0xF & bow=0x1 & tbl_bzero & postIncrementStore) ... & SRC_B_AS ... & DEST_B_AD ... {
|
|
# Operation Flags...
|
|
$(OVERFLOW) = 0x0; # V Flag
|
|
# Operation...
|
|
result:1 = DEST_B_AD & SRC_B_AS;
|
|
DEST_B_AD = result;
|
|
build tbl_bzero;
|
|
# Result Flags...
|
|
$(SIGN) = (result s< 0x0); # S Flag
|
|
$(ZERO) = (result == 0x0); # Z Flag
|
|
$(CARRY) = (result != 0x0); # C Flag
|
|
build postIncrementStore;
|
|
}
|