#TODO: relative branches are not computed as addresses in []

# TODO: byte oriented inst_next/inst_start must be changed to word oriented when storing into reg/stack...


# NOTE: No support for stack pointer limit register (SPLIM)
# NOTE: Some registers are larger than PIC defines.
# NOTE: No support for signal emulation.
# NOTE: No support for mapping a 32Kbyte section of program memory space into upper 32 Kbytes of data address space.
# NOTE: No repeat loop status bit.
# NOTE: Split flags register, which could cause side effects.
# NOTE: pwrsav pcode is not defined.
# TODO: Support for fractional multiplier mode.
# TODO: Check ACCA and ACCB staturation modes.
# TODO: Check accumulator staturation and rounding modes.
# TODO: Test Stack Frame Active (SFA) status bit.

# Basic ================================================================================

#define endian=little; # little endian only
define alignment=2;    # 2 signifies how the PC moves per instruction

define space ram       type=ram_space 	    size=2;                       # (2x8=)16-bit address space
define space register  type=register_space  size=2;                       # (2x8=)16-bit address space
define space rom       type=ram_space       size=3 wordsize=2 default ;   # (3x8=)24-bit address space
                                                                          # (2x8=)16-bit word per address
                                                                          # 24-bit canonical instruction:
                                                                          #   address  :      code
                                                                          #          0 :  byte2 | byte1
                                                                          #          1 :   pad  | byte3
                                                                          #          2 :  byte2 | byte1
                                                                          #          3 :   pad  | byte3
                                                                          #   .
                                                                          #   .
                                                                          #   .
                                                                          #   etc


# Registers ============================================================================

define ram offset=0 size=2 [
  W0   W1   W2   W3   W4   W5   W6   W7   W8   W9   W10  W11  W12  W13  W14  W15 
];

define ram offset=0 size=4 [
  W1W0   W3W2   W5W4   W7W6   W9W8  W11W10  W13W12  W15W14 
];

# define ram offset=28 size=3 [ FP ];
# define ram offset=32 size=3 [ SP ];

# Note: This assumes little endian only
define ram offset=0 size=1 [
  W0byte   _   W1byte   _   W2byte   _   W3byte   _
  W4byte   _   W5byte   _   W6byte   _   W7byte   _   
  W8byte   _   W9byte   _  W10byte   _  W11byte   _
  W12byte  _  W13byte   _  W14byte   _  W15byte   _
];

define register offset=0 size=2 [
  SHADOW_W0  SHADOW_W1  SHADOW_W2  SHADOW_W3
];

define ram offset=0x20 size=2 [ SPLIM ]; # Stack Pointer Limit

# Note: ACCxU implemented here as a 16 bit, actual register is only 8 bits in PIC3x
# Note: This assumes little endian only
define ram offset=0x22 size=2 [
  ACCAL   ACCAH   ACCAU
  ACCBL   ACCBH   ACCBU
];

# Note: Like above ACCx implemented here as a 48 bit, actual register is only 40 bits in PIC3x
define ram offset=0x22 size=6 [
  ACCA
  ACCB
];

define ram offset=0x2E size=3 [ PC ];

@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
define ram offset=0x32 size=2 [ DSRPAG ];  # 9bit Data Space Read Page Address
define ram offset=0x34 size=2 [ DSWPAG ];  # 8bit Data Space Write Page Address
define ram offset=0x36 size=2 [ RCOUNT ];  # Repeat counter
# TODO: Re-implement with shadow stack
# define ram offset=0x38 size=2 [ DCOUNT ];  # 13 bits long                    DO Loop counter
define ram offset=0x54 size=1 [ TBLPAG ];  # 7bit Data Table Page Address
@else
define ram offset=0x32 size=1 [ TBLPAG ];  # 8bit Data Table Page Address
define ram offset=0x34 size=1 [ PSVPAG ];  # Program Memory Visibility Page Address Pointer
define ram offset=0x36 size=2 [ RCOUNT ];  # Repeat counter
define ram offset=0x38 size=2 [ DCOUNT ];  # 13 bits long                    DO Loop counter
define ram offset=0x3A size=3 [ DOSTART ];
define ram offset=0x3C size=3 [ DOEND ];
@endif  

define ram offset=0x44 size=2 [ CORCON ];  # Core Control Register
define ram offset=0x46 size=2 [ MODCON ];
define ram offset=0x48 size=2 [ XMODSRT ];
define ram offset=0x4A size=2 [ XMODEND ];
define ram offset=0x4C size=2 [ YMODSRT ];
define ram offset=0x4E size=2 [ YMODEND ];
define ram offset=0x50 size=2 [ XBREV ];
define ram offset=0x52 size=2 [ DISICNT ];  # Disable Interrupts Counter

# Control registers
define register offset=1024 size=1 [
  SRL
  SRH
];

# SR component register fields (pseudo)
define register offset=1536 size=1 [
  SRH_OA
  SRH_OB
  SRH_SA
  SRH_SB
  SRH_OAB
  SRH_SAB
  SRH_DA
  SRH_DC

  SRL_IPL2
  SRL_IPL1
  SRL_IPL0
  SRL_RA
  SRL_N
  SRL_OV
  SRL_Z
  SRL_C

  DISI

  SHADOW_SRH_DC

  SHADOW_SRL_N
  SHADOW_SRL_OV
  SHADOW_SRL_Z
  SHADOW_SRL_C
];


# System register - Program Counter
# Note: actual PC is 23-bits wide, with a fixed 0 for the zeroeth bit
define register offset=2048 size=3 [
	# dsPIC33E uses array of registers to have 4 deep zero overhead do loops
@if defined(dsPIC33E) || defined(dsPIC33C)
  DOSTART  # 24 bits long bit23=bit0=0       DO Loop Start Address
  DOSTART1
  DOSTART2
  DOSTART3
  DOEND    # 24 bits long bit23=bit0=0       DO Loop End Address
  DOEND1
  DOEND2
  DOEND3
@endif
  DOSTART_SHADOW
  DOEND_SHADOW
];


# System register - CPU Core Control Register # ????? connect this to meta-model?
define register offset=2560 size=2 [
  WDTcount      # ????? formal name not documented, true size unknown
  WDTprescalarA # ????? formal name not documented, true size unknown
  WDTprescalarB # ????? formal name not documented, true size unknown
];


# CORCON component register fields (pseudo)
define register offset=3072 size=1 [
  CORCON_VAR
  CORCON_IPL3
  CORCON_PSV
  CORCON_SFA
@if defined(dsPIC33E) || defined(dsPIC33C)
  CORCON_DL # DO loop nesting level status bits (3 bit long)
@endif
];


# NOTE: Technically this section only apply to dsPIC30F, dsPIC33F, dsPIC33E, and dsPIC33C but we will allow all profiles to see it.

# This supports the zero overhead do loop specific registers
define register offset=4096 size=2 [

# dsPIC33E uses array of registers to have 4 deep zero overhead do loops
@if defined(dsPIC33E) || defined(dsPIC33C)
  DCOUNT   # 13 bits long                    DO Loop counter
  DCOUNT1 
  DCOUNT2 
  DCOUNT3
@else
# dsPIC30 and dsPIC33F use shadow register to have allow one level deep zero overhead do loop (doesn't hurt to have in other variants)
  DCOUNT_SHADOW 
@endif
];

# This supports the "skip next instruction" conditionals
define register offset=4608 size=1 [
  SkipNextFlag    # pseudo run-time register to flag skipping over this instruction (making it a NOP)
];


# contextreg is our instruction context
# here we are only using it for zero overhead do loops

# NOTE: At first i used size=2 and it seem to be having problems?
define register offset=5120 size=4 [ contextreg ];

define context contextreg 
  blockEnd=(0,0) noflow    # Flag to indicate end do zero overhead do loop
  phase=(2,3)        # Flag to indicate that we are in the middle of a instruction and not to change context
  repeatInstr=(4,4) noflow # Flag to indicate end of repeat instruction loop
  skipInstr=(5,5) noflow
                     # Flag to indicate that we are in the next instruction after a "skip next instruction" command
;

# Tokens ============================================================================

define token instr(32)
  padding=(24,31) # padding for 4th byte that is not decoded in actual processor
  OP_31_0 =(0,31)
  OP_31_4 =(4,31)
  
  OP_23_0 =(0,23)
  OP_23_1 =(1,23)
  OP_23_4 =(4,23)
  OP_23_11=(11,23)
  OP_23_12=(12,23)
  OP_23_14=(14,23)
  OP_23_15=(15,23)
  OP_23_16=(16,23)
  OP_23_18=(18,23)
  OP_23_19=(19,23)
  OP_23_20=(20,23)
  
  OP_21_20=(20,21)
  
  OP_19_16=(16,19)
  OP_19_17=(17,19)
  OP_19_18=(18,19)
  
  OP_15_8 =(8,15)
  OP_15_12=(12,15)
  OP_15_14=(14,15)
  
  OP_14_0 =(0,14)
  OP_14_4 =(4,14)
  OP_14_6 =(6,14)
  OP_14_7 =(7,14)
  OP_14_11=(11,14)
  OP_14_12=(12,14)
  
  OP_13_4 =(4,13)
  
  OP_11_7 =(7,11)
  OP_11_8 =(8,11)
  OP_11_10=(10,11)
  
  OP_10_8 =(8,10)
  OP_10_7 =(7,10)
  OP_10_4 =(4,10)
  
  OP_9_4  =(4,9)
  OP_9_8  =(8,9)
  
  OP_7_0  =(0,7)
  OP_7_4  =(4,7)
  OP_7_5  =(5,7)
  OP_7_6  =(6,7)
  
  OP_6_0  =(0,6)
  OP_6_4  =(4,6)
  OP_6_5  =(5,6)
  
  OP_5_4  =(4,5)
  
  OP_3_0  =(0,3) 
  
  OP_1_0  =(0,1)
  
  OP_19   =(19,19)
  OP_15   =(15,15)
  OP_14   =(14,14)
  OP_13   =(13,13)
  OP_12   =(12,12)
  OP_11   =(11,11)
  OP_7    =(7,7)
  OP_6    =(6,6)
  OP_5    =(5,5)
  OP_3    =(3,3)
  OP_0    =(0,0)
  
  TOK_n    =(16,16)
  TOK_A    =(15,15)
  TOK_B    =(14,14)
  TOK_Bb   =(10,10)
  TOK_CCCC =(16,19)
  TOK_D    =(13,13)
  TOK_W    =(6,6)
  TOK_Z    =(15,15)
  TOK_Zb   =(11,11)

  TOK_f12  =(1,12)
  TOK_f13  =(0,12)
  TOK_f15  =(1,15)
  TOK_f15b =(4,18)
  TOK_k3   =(0,2)
  TOK_k4   =(0,3)
  TOK_k5   =(0,4)
  TOK_k6   =(0,5) signed
  TOK_k8a  =(0,4)
  TOK_k4b  =(4,7)
  TOK_k8b  =(7,9)
  TOK_k8c  =(4,11)
  TOK_k10  =(4,13)
  TOK_k14  =(0,13)
  TOK_k15  =(0,14)
  TOK_k16  =(4,19)
  TOK_k16t =(0,15)
  
  TOK_r4         =(7,10) signed
  TOK_bit4word   =(0,0)
  TOK_b3         =(13,15)
  TOK_b1         =(0,0)
  TOK_b4         =(12,15)
  TOK_n6         =(4,9) signed
  TOK_n7         =(0,6)
  TOK_n15        =(1,15)
  TOK_n16        =(0,15) signed

  TOK_0          =(0,0)
  TOK_7          =(7,7)
  TOK_13		 =(13,13)
  
  TOK_3_0_Wreg   =(0,3) # 16-bit full reg
  TOK_3_0_Breg   =(0,3) # 8-bit LSB of reg
  TOK_3_1_Dreg   =(1,3) # 32-bit reg pair, e.g., W1:W0
  TOK_3_1_Dregn  =(1,3) # 32-bit reg pair name, e.g., W0
  
  TOK_4_0_U      =(0,4)
   
  TOK_6_4_U      =(4,6)
    
  TOK_9_0_U      =(0,9) 

  TOK_10_7_Wreg  =(7,10) # 16-bit full reg
  TOK_10_7_Breg  =(7,10) # 8-bit LSB of reg
  TOK_10_7_Wregp =(7,10) # 16-bit full reg offset by one
  TOK_10_8_Dreg  =(8,10) # 32-bit reg pair, e.g., W1:W0
  TOK_10_8_Dregn =(8,10) # 32-bit reg pair name, e.g., W0
  
  TOK_11_8_Wreg  =(8,11) # 16-bit full reg

  TOK_13_11_U    =(11,13)

  TOK_14_12_Dreg =(12,14) # 32-bit reg pair, e.g., W1:W0
  TOK_14_12_Dregn=(12,14) # 32-bit reg pair name, e.g., W0
  TOK_14_11_Wreg =(11,14) # 16-bit full reg
  TOK_14_11_Wregn=(11,14) # 16-bit full reg offset by one
  TOK_14_11_Breg =(11,14) # 8-bit LSB of reg

  TOK_18_15_Wreg =(15,18) # 16-bit full reg
  TOK_18_15_Breg =(15,18) # 8-bit LSB of reg
  TOK_18_15_S    =(15,18) signed
  
  TOK_17_16_mm   =(16,17)
  TOK_18_16_mmm  =(16,18)
  TOK_13_12_xx   =(12,13)
  TOK_13_12_kk   =(12,13)
  TOK_11_10_yy   =(10,11)
  TOK_11_10_PP   =(10,11)
  TOK_9_6_iiii   =(6,9)
  TOK_5_2_jjjj   =(2,5)
  TOK_1_0_aa     =(0,1)
  ;




# Attach variables =====================================================

# attach normal registers 
attach variables [ TOK_18_15_Wreg TOK_3_0_Wreg TOK_10_7_Wreg TOK_11_8_Wreg TOK_14_11_Wreg ] [

  W0   W1   W2   W3   W4   W5   W6   W7   W8   W9   W10  W11  W12  W13  W14  W15
];

attach variables [ TOK_14_11_Wregn ] [
	_		W0		W1		W2		W3		W4		W5		W6
	W7		W8		W9		W10		W11		W12		W13		W14
];

attach variables [ TOK_10_7_Wregp ] [
	W0		W1		W2		W3		W4		W5		W6		W7
	W8		W9		W10		W11		W12		W13		W14		W0
];

# attach lower byte sub-registers
attach variables [ TOK_18_15_Breg TOK_3_0_Breg TOK_10_7_Breg TOK_14_11_Breg ] [

  W0byte   W1byte   W2byte   W3byte   W4byte   W5byte   W6byte   W7byte
  W8byte   W9byte   W10byte  W11byte  W12byte  W13byte  W14byte  W15byte
];

# attach double registers (ref by even reg only)
attach variables [ TOK_3_1_Dreg TOK_10_8_Dreg TOK_14_12_Dreg ] [

   W1W0 		W3W2    W5W4    W7W6    W9W8   W11W10   W13W12   W15W14  
];
attach variables [ TOK_3_1_Dregn TOK_10_8_Dregn  TOK_14_12_Dregn ] [

   W0 	W2    W4    W6    W8   W10   W12   W14  
];


# Sub-constructors ====================================================================
 
@define WSconstraint "(OP_6=0 | OP_5=0)"
@define WDconstraint "(OP_13=0 | OP_12=0)"

# Use must be constrained by $(WSconstraint)
Ws_t: TOK_3_0_Wreg                              is TOK_6_4_U=0x0 & TOK_3_0_Wreg
  { export TOK_3_0_Wreg; }

Ws_t: "["TOK_3_0_Wreg"]"                        is TOK_6_4_U=0x1 & TOK_3_0_Wreg
  { export *[ram]:2 TOK_3_0_Wreg; }

Ws_t: "["TOK_3_0_Wreg"--]"                      is TOK_6_4_U=0x2 & TOK_3_0_Wreg
  { tmp:2 = TOK_3_0_Wreg; TOK_3_0_Wreg = TOK_3_0_Wreg - 2; export *[ram]:2  tmp; }

Ws_t: "["TOK_3_0_Wreg"++]"                      is TOK_6_4_U=0x3 & TOK_3_0_Wreg
  { tmp:2 =  TOK_3_0_Wreg; TOK_3_0_Wreg = TOK_3_0_Wreg + 2; export *[ram]:2 tmp; }

Ws_t: "[--"TOK_3_0_Wreg"]"                      is TOK_6_4_U=0x4 & TOK_3_0_Wreg
  { TOK_3_0_Wreg = TOK_3_0_Wreg - 2; export *[ram]:2 TOK_3_0_Wreg; }

Ws_t: "[++"TOK_3_0_Wreg"]"                      is TOK_6_4_U=0x5 & TOK_3_0_Wreg
  { TOK_3_0_Wreg = TOK_3_0_Wreg + 2; export *[ram]:2 TOK_3_0_Wreg; }


# Use must be constrained by $(WSconstraint)
Wsd_t: TOK_3_0_Wreg                              is TOK_6_4_U=0x0 & TOK_3_0_Wreg & TOK_3_1_Dreg & OP_0=0
  { export TOK_3_1_Dreg; }

Wsd_t: "["TOK_3_0_Wreg"]"                        is TOK_6_4_U=0x1 & TOK_3_0_Wreg
  { export *[ram]:4 TOK_3_0_Wreg; }

Wsd_t: "["TOK_3_0_Wreg"--]"                      is TOK_6_4_U=0x2 & TOK_3_0_Wreg
  { tmp:2 = TOK_3_0_Wreg; TOK_3_0_Wreg = TOK_3_0_Wreg - 4; export *[ram]:4  tmp; }

Wsd_t: "["TOK_3_0_Wreg"++]"                      is TOK_6_4_U=0x3 & TOK_3_0_Wreg
  { tmp:2 =  TOK_3_0_Wreg; TOK_3_0_Wreg = TOK_3_0_Wreg + 4; export *[ram]:4 tmp; }

Wsd_t: "[--"TOK_3_0_Wreg"]"                      is TOK_6_4_U=0x4 & TOK_3_0_Wreg
  { TOK_3_0_Wreg = TOK_3_0_Wreg - 4; export *[ram]:4 TOK_3_0_Wreg; }

Wsd_t: "[++"TOK_3_0_Wreg"]"                      is TOK_6_4_U=0x5 & TOK_3_0_Wreg
  { TOK_3_0_Wreg = TOK_3_0_Wreg + 4; export *[ram]:4 TOK_3_0_Wreg; }


# Use must be constrained by $(WSconstraint)
Wsnd_t: TOK_3_0_Wreg                              is TOK_13_11_U=0x0 & TOK_3_0_Wreg & TOK_3_1_Dreg & OP_0=0
  { export TOK_3_1_Dreg; }

Wsnd_t: "["TOK_3_0_Wreg"]"                        is TOK_13_11_U=0x1 & TOK_3_0_Wreg
  { export *[ram]:4 TOK_3_0_Wreg; }

Wsnd_t: "["TOK_3_0_Wreg"--]"                      is TOK_13_11_U=0x2 & TOK_3_0_Wreg
  { tmp:2 = TOK_3_0_Wreg; TOK_3_0_Wreg = TOK_3_0_Wreg - 4; export *[ram]:4  tmp; }

Wsnd_t: "["TOK_3_0_Wreg"++]"                      is TOK_13_11_U=0x3 & TOK_3_0_Wreg
  { tmp:2 =  TOK_3_0_Wreg; TOK_3_0_Wreg = TOK_3_0_Wreg + 4; export *[ram]:4 tmp; }

Wsnd_t: "[--"TOK_3_0_Wreg"]"                      is TOK_13_11_U=0x4 & TOK_3_0_Wreg
  { TOK_3_0_Wreg = TOK_3_0_Wreg - 4; export *[ram]:4 TOK_3_0_Wreg; }

Wsnd_t: "[++"TOK_3_0_Wreg"]"                      is TOK_13_11_U=0x5 & TOK_3_0_Wreg
  { TOK_3_0_Wreg = TOK_3_0_Wreg + 4; export *[ram]:4 TOK_3_0_Wreg; }


# Use must be constrained by $(WSconstraint)
Wsb_t: TOK_3_0_Wreg                             is TOK_6_4_U=0x0 & TOK_3_0_Wreg
  { export TOK_3_0_Wreg; }

Wsb_t: "["TOK_3_0_Wreg"]"                       is TOK_6_4_U=0x1 & TOK_3_0_Wreg
  { export *[ram]:2 TOK_3_0_Wreg; }

Wsb_t: "["TOK_3_0_Wreg"--]"                     is TOK_6_4_U=0x2 & TOK_3_0_Wreg
  { tmp:2 = TOK_3_0_Wreg; TOK_3_0_Wreg = TOK_3_0_Wreg - 2; export *[ram]:2 tmp; }

Wsb_t: "["TOK_3_0_Wreg"++]"                     is TOK_6_4_U=0x3 & TOK_3_0_Wreg
  { tmp:2 = TOK_3_0_Wreg; TOK_3_0_Wreg = TOK_3_0_Wreg + 2; export *[ram]:2 tmp; }

Wsb_t: "[--"TOK_3_0_Wreg"]"                     is TOK_6_4_U=0x4 & TOK_3_0_Wreg
  { TOK_3_0_Wreg = TOK_3_0_Wreg - 2; export *[ram]:2 TOK_3_0_Wreg; }

Wsb_t: "[++"TOK_3_0_Wreg"]"                     is TOK_6_4_U=0x5 & TOK_3_0_Wreg
  { TOK_3_0_Wreg = TOK_3_0_Wreg + 2; export *[ram]:2 TOK_3_0_Wreg; }


# Use must be constrained by $(WSconstraint)
Wsbyte_t: TOK_3_0_Wreg                          is TOK_6_4_U=0x0 & TOK_3_0_Wreg & TOK_3_0_Breg
  { export TOK_3_0_Breg; }

Wsbyte_t: "["TOK_3_0_Wreg"]"                    is TOK_6_4_U=0x1 & TOK_3_0_Wreg
  { export *[ram]:1 TOK_3_0_Wreg; }

Wsbyte_t: "["TOK_3_0_Wreg"--]"                  is TOK_6_4_U=0x2 & TOK_3_0_Wreg
  { local tmp =  TOK_3_0_Wreg; TOK_3_0_Wreg = TOK_3_0_Wreg - 1; export *[ram]:1 tmp; }

Wsbyte_t: "["TOK_3_0_Wreg"++]"                  is TOK_6_4_U=0x3 & TOK_3_0_Wreg
  { local tmp = TOK_3_0_Wreg; TOK_3_0_Wreg = TOK_3_0_Wreg + 1; export *[ram]:1 tmp; }

Wsbyte_t: "[--"TOK_3_0_Wreg"]"                  is TOK_6_4_U=0x4 & TOK_3_0_Wreg
  { TOK_3_0_Wreg = TOK_3_0_Wreg - 1; export *[ram]:1 TOK_3_0_Wreg; }

Wsbyte_t: "[++"TOK_3_0_Wreg"]"                  is TOK_6_4_U=0x5 & TOK_3_0_Wreg
  { TOK_3_0_Wreg = TOK_3_0_Wreg + 1; export *[ram]:1 TOK_3_0_Wreg; }


# Use must be constrained by $(WSconstraint)
Wsbbyte_t: TOK_3_0_Wreg                         is TOK_6_4_U=0x0 & TOK_3_0_Wreg & TOK_3_0_Breg
  { export TOK_3_0_Breg; }

Wsbbyte_t: "["TOK_3_0_Wreg"]"                   is TOK_6_4_U=0x1 & TOK_3_0_Wreg
  { export *[ram]:1 TOK_3_0_Wreg; }

Wsbbyte_t: "["TOK_3_0_Wreg"--]"                 is TOK_6_4_U=0x2 & TOK_3_0_Wreg
  { local tmp = TOK_3_0_Wreg; TOK_3_0_Wreg = TOK_3_0_Wreg - 1; export *[ram]:1 tmp; }

Wsbbyte_t: "["TOK_3_0_Wreg"++]"                 is TOK_6_4_U=0x3 & TOK_3_0_Wreg
  { local tmp = TOK_3_0_Wreg; TOK_3_0_Wreg = TOK_3_0_Wreg + 1; export *[ram]:1 tmp; }

Wsbbyte_t: "[--"TOK_3_0_Wreg"]"                 is TOK_6_4_U=0x4 & TOK_3_0_Wreg
  { TOK_3_0_Wreg = TOK_3_0_Wreg - 1; export *[ram]:1 TOK_3_0_Wreg; }

Wsbbyte_t: "[++"TOK_3_0_Wreg"]"                 is TOK_6_4_U=0x5 & TOK_3_0_Wreg
  { TOK_3_0_Wreg = TOK_3_0_Wreg + 1; export *[ram]:1 TOK_3_0_Wreg; }


# Use must be constrained by $(WDconstraint)
Wd_t: TOK_10_7_Wreg                             is TOK_13_11_U=0x0 & TOK_10_7_Wreg
  { export TOK_10_7_Wreg; }

Wd_t: "["TOK_10_7_Wreg"]"                       is TOK_13_11_U=0x1 & TOK_10_7_Wreg
  { export *[ram]:2 TOK_10_7_Wreg; }

Wd_t: "["TOK_10_7_Wreg"--]"                     is TOK_13_11_U=0x2 & TOK_10_7_Wreg
  { local tmp = TOK_10_7_Wreg; TOK_10_7_Wreg = TOK_10_7_Wreg - 2; export *[ram]:2 tmp; }

Wd_t: "["TOK_10_7_Wreg"++]"                     is TOK_13_11_U=0x3 & TOK_10_7_Wreg
  { local tmp = TOK_10_7_Wreg; TOK_10_7_Wreg = TOK_10_7_Wreg + 2; export *[ram]:2 tmp; }

Wd_t: "[--"TOK_10_7_Wreg"]"                     is TOK_13_11_U=0x4 & TOK_10_7_Wreg
  { TOK_10_7_Wreg = TOK_10_7_Wreg - 2; export *[ram]:2 TOK_10_7_Wreg; }

Wd_t: "[++"TOK_10_7_Wreg"]"                     is TOK_13_11_U=0x5 & TOK_10_7_Wreg
  { TOK_10_7_Wreg = TOK_10_7_Wreg + 2; export *[ram]:2 TOK_10_7_Wreg; }


# Use must be constrained by $(WDconstraint)
Wdd_t: TOK_10_7_Wreg                             is TOK_13_11_U=0x0 & TOK_10_7_Wreg & TOK_10_8_Dreg & OP_7=0
  { export TOK_10_8_Dreg; }

Wdd_t: "["TOK_10_7_Wreg"]"                       is TOK_13_11_U=0x1 & TOK_10_7_Wreg
  { export *[ram]:4 TOK_10_7_Wreg; }

Wdd_t: "["TOK_10_7_Wreg"--]"                     is TOK_13_11_U=0x2 & TOK_10_7_Wreg
  { local tmp = TOK_10_7_Wreg; TOK_10_7_Wreg = TOK_10_7_Wreg - 4; export *[ram]:4 tmp; }

Wdd_t: "["TOK_10_7_Wreg"++]"                     is TOK_13_11_U=0x3 & TOK_10_7_Wreg
  { local tmp = TOK_10_7_Wreg; TOK_10_7_Wreg = TOK_10_7_Wreg + 4; export *[ram]:4 tmp; }

Wdd_t: "[--"TOK_10_7_Wreg"]"                     is TOK_13_11_U=0x4 & TOK_10_7_Wreg
  { TOK_10_7_Wreg = TOK_10_7_Wreg - 4; export *[ram]:4 TOK_10_7_Wreg; }

Wdd_t: "[++"TOK_10_7_Wreg"]"                     is TOK_13_11_U=0x5 & TOK_10_7_Wreg
  { TOK_10_7_Wreg = TOK_10_7_Wreg + 4; export *[ram]:4 TOK_10_7_Wreg; }


# Use must be constrained by $(WDconstraint)
Wdbyte_t: TOK_10_7_Wreg                         is TOK_13_11_U=0x0 & TOK_10_7_Wreg & TOK_10_7_Breg
  { export TOK_10_7_Breg; }

Wdbyte_t: "["TOK_10_7_Wreg"]"                   is TOK_13_11_U=0x1 & TOK_10_7_Wreg
  { export *[ram]:1 TOK_10_7_Wreg; }

Wdbyte_t: "["TOK_10_7_Wreg"--]"                 is TOK_13_11_U=0x2 & TOK_10_7_Wreg
  { local tmp = TOK_10_7_Wreg; TOK_10_7_Wreg = TOK_10_7_Wreg - 1; export *[ram]:1 tmp; }

Wdbyte_t: "["TOK_10_7_Wreg"++]"                 is TOK_13_11_U=0x3 & TOK_10_7_Wreg
  { local tmp = TOK_10_7_Wreg; TOK_10_7_Wreg = TOK_10_7_Wreg + 1; export *[ram]:1 tmp; }

Wdbyte_t: "[--"TOK_10_7_Wreg"]"                 is TOK_13_11_U=0x4 & TOK_10_7_Wreg
  { TOK_10_7_Wreg = TOK_10_7_Wreg - 1; export *[ram]:1 TOK_10_7_Wreg; }

Wdbyte_t: "[++"TOK_10_7_Wreg"]"                 is TOK_13_11_U=0x5 & TOK_10_7_Wreg
  { TOK_10_7_Wreg = TOK_10_7_Wreg + 1; export *[ram]:1 TOK_10_7_Wreg; }


# A lot like WdWRD_t
movWs: TOK_3_0_Wreg                           is TOK_6_4_U=0x0 & TOK_3_0_Wreg
  { export TOK_3_0_Wreg; }

movWs: "["TOK_3_0_Wreg"]"                     is TOK_6_4_U=0x1 & TOK_3_0_Wreg
  { export *[ram]:2 TOK_3_0_Wreg; }

movWs: "["TOK_3_0_Wreg"--]"                   is TOK_6_4_U=0x2 & TOK_3_0_Wreg
  { tmp:2 = TOK_3_0_Wreg; TOK_3_0_Wreg = TOK_3_0_Wreg - 2; export *[ram]:2 tmp; }

movWs: "["TOK_3_0_Wreg"++]"                   is TOK_6_4_U=0x3 & TOK_3_0_Wreg
  { local tmp = TOK_3_0_Wreg; TOK_3_0_Wreg = TOK_3_0_Wreg + 2; export *[ram]:2 tmp; }

movWs: "[--"TOK_3_0_Wreg"]"                   is TOK_6_4_U=0x4 & TOK_3_0_Wreg
  { TOK_3_0_Wreg = TOK_3_0_Wreg - 2; export *[ram]:2 TOK_3_0_Wreg; }

movWs: "[++"TOK_3_0_Wreg"]"                   is TOK_6_4_U=0x5 & TOK_3_0_Wreg
  { TOK_3_0_Wreg = TOK_3_0_Wreg + 2; export *[ram]:2 TOK_3_0_Wreg; }

movWs: "["TOK_3_0_Wreg"+"TOK_18_15_Wreg"]"      is TOK_6_4_U=0x6 & TOK_18_15_Wreg & TOK_3_0_Wreg
  { local tmp = (TOK_3_0_Wreg + TOK_18_15_Wreg); export *[ram]:2 tmp; }

movWs: "["TOK_3_0_Wreg"+"TOK_18_15_Wreg"]"      is TOK_6_4_U=0x7 & TOK_18_15_Wreg & TOK_3_0_Wreg
  { local tmp = (TOK_3_0_Wreg + TOK_18_15_Wreg); export *[ram]:2 tmp; }


movWsbyte: TOK_3_0_Wreg                           is TOK_6_4_U=0x0 & TOK_3_0_Wreg & TOK_3_0_Breg
  { export TOK_3_0_Breg; }

movWsbyte: "["TOK_3_0_Wreg"]"                     is TOK_6_4_U=0x1 & TOK_3_0_Wreg
  { export *[ram]:1 TOK_3_0_Wreg; }

movWsbyte: "["TOK_3_0_Wreg"--]"                   is TOK_6_4_U=0x2 & TOK_3_0_Wreg
  { tmp:2 = TOK_3_0_Wreg; TOK_3_0_Wreg = TOK_3_0_Wreg - 1; export *[ram]:1 tmp; }

movWsbyte: "["TOK_3_0_Wreg"++]"                   is TOK_6_4_U=0x3 & TOK_3_0_Wreg
  { tmp:2 = TOK_3_0_Wreg; TOK_3_0_Wreg = TOK_3_0_Wreg + 1; export *[ram]:1 tmp; }

movWsbyte: "[--"TOK_3_0_Wreg"]"                   is TOK_6_4_U=0x4 & TOK_3_0_Wreg
  { TOK_3_0_Wreg = TOK_3_0_Wreg - 1; export *[ram]:1 TOK_3_0_Wreg; }

movWsbyte: "[++"TOK_3_0_Wreg"]"                   is TOK_6_4_U=0x5 & TOK_3_0_Wreg
  { TOK_3_0_Wreg = TOK_3_0_Wreg + 1; export *[ram]:1 TOK_3_0_Wreg; }

movWsbyte: "["TOK_3_0_Wreg"+"TOK_18_15_Wreg"]"      is TOK_6_4_U=0x6 & TOK_18_15_Wreg & TOK_3_0_Wreg
  { tmp:2 = (TOK_3_0_Wreg + TOK_18_15_Wreg); export *[ram]:1 tmp; }

movWsbyte: "["TOK_3_0_Wreg"+"TOK_18_15_Wreg"]"      is TOK_6_4_U=0x7 & TOK_18_15_Wreg & TOK_3_0_Wreg
  { tmp:2 = (TOK_3_0_Wreg + TOK_18_15_Wreg); export *[ram]:1 tmp; }



movWd: TOK_10_7_Wreg                           is TOK_13_11_U=0x0 & TOK_10_7_Wreg
  { export TOK_10_7_Wreg; }

movWd: "["TOK_10_7_Wreg"]"                     is TOK_13_11_U=0x1 & TOK_10_7_Wreg
  { export *[ram]:2 TOK_10_7_Wreg; }

movWd: "["TOK_10_7_Wreg"--]"                   is TOK_13_11_U=0x2 & TOK_10_7_Wreg
  { tmp:2 = TOK_10_7_Wreg; TOK_10_7_Wreg = TOK_10_7_Wreg - 2; export *[ram]:2 tmp; }

movWd: "["TOK_10_7_Wreg"++]"                   is TOK_13_11_U=0x3 & TOK_10_7_Wreg
  { tmp:2 = TOK_10_7_Wreg; TOK_10_7_Wreg = TOK_10_7_Wreg + 2; export *[ram]:2 tmp; }

movWd: "[--"TOK_10_7_Wreg"]"                   is TOK_13_11_U=0x4 & TOK_10_7_Wreg
  { TOK_10_7_Wreg = TOK_10_7_Wreg - 2; export *[ram]:2 TOK_10_7_Wreg; }

movWd: "[++"TOK_10_7_Wreg"]"                   is TOK_13_11_U=0x5 & TOK_10_7_Wreg
  { TOK_10_7_Wreg = TOK_10_7_Wreg + 2; export *[ram]:2 TOK_10_7_Wreg; }

movWd: "["TOK_10_7_Wreg"+"TOK_18_15_Wreg"]"      is TOK_13_11_U=0x6 & TOK_18_15_Wreg & TOK_10_7_Wreg
  { tmp:2 = (TOK_10_7_Wreg + TOK_18_15_Wreg); export *[ram]:2 tmp; }

movWd: "["TOK_10_7_Wreg"+"TOK_18_15_Wreg"]"      is TOK_13_11_U=0x7 & TOK_18_15_Wreg & TOK_10_7_Wreg
  { tmp:2 = (TOK_10_7_Wreg + TOK_18_15_Wreg); export *[ram]:2 tmp; }



movWdbyte: TOK_10_7_Wreg                           is TOK_13_11_U=0x0 & TOK_10_7_Wreg & TOK_10_7_Breg
  { export TOK_10_7_Breg; }

movWdbyte: "["TOK_10_7_Wreg"]"                     is TOK_13_11_U=0x1 & TOK_10_7_Wreg
  { export *[ram]:1 TOK_10_7_Wreg; }

movWdbyte: "["TOK_10_7_Wreg"--]"                   is TOK_13_11_U=0x2 & TOK_10_7_Wreg
  { tmp:2 = TOK_10_7_Wreg; TOK_10_7_Wreg = TOK_10_7_Wreg - 1; export *[ram]:1  tmp; }

movWdbyte: "["TOK_10_7_Wreg"++]"                   is TOK_13_11_U=0x3 & TOK_10_7_Wreg
  { tmp:2 = TOK_10_7_Wreg; TOK_10_7_Wreg = TOK_10_7_Wreg + 1; export *[ram]:1 tmp; }

movWdbyte: "[--"TOK_10_7_Wreg"]"                   is TOK_13_11_U=0x4 & TOK_10_7_Wreg
  { TOK_10_7_Wreg = TOK_10_7_Wreg - 1; export *[ram]:1 TOK_10_7_Wreg; }

movWdbyte: "[++"TOK_10_7_Wreg"]"                   is TOK_13_11_U=0x5 & TOK_10_7_Wreg
  { TOK_10_7_Wreg = TOK_10_7_Wreg + 1; export *[ram]:1 TOK_10_7_Wreg; }

movWdbyte: "["TOK_10_7_Wreg"+"TOK_18_15_Wreg"]"      is TOK_13_11_U=0x6 & TOK_18_15_Wreg & TOK_10_7_Wreg
  { tmp:2 = (TOK_10_7_Wreg + TOK_18_15_Wreg); export *[ram]:1 tmp; }

movWdbyte: "["TOK_10_7_Wreg"+"TOK_18_15_Wreg"]"      is TOK_13_11_U=0x7 & TOK_18_15_Wreg & TOK_10_7_Wreg
  { tmp:2 = (TOK_10_7_Wreg + TOK_18_15_Wreg); export *[ram]:1 tmp; }





Wn_t:      TOK_3_0_Wreg                         is TOK_3_0_Wreg
  { export TOK_3_0_Wreg; }

Wnbyte_t:  TOK_3_0_Wreg                         is TOK_3_0_Wreg & TOK_3_0_Breg
  { export TOK_3_0_Breg; }

Wnd_t:     TOK_10_7_Wreg                        is TOK_10_7_Wreg
  { export TOK_10_7_Wreg; }
  
Wndd_t:     TOK_10_8_Dregn                      is TOK_10_8_Dreg & TOK_10_8_Dregn
  { export TOK_10_8_Dreg; }

Wnda_t:    TOK_10_7_Wreg                        is TOK_10_7_Wreg
  { export TOK_10_7_Wreg; }

Wnbf_t:    TOK_11_8_Wreg                        is TOK_11_8_Wreg
  { export TOK_11_8_Wreg; }
  
Wdpp_t: "["TOK_10_7_Wreg"++]"                   is TOK_10_7_Wreg
  { local tmp = TOK_10_7_Wreg; TOK_10_7_Wreg = TOK_10_7_Wreg + 2; export *[ram]:2 tmp; }
  
Wndabyte_t: TOK_10_7_Wreg                       is TOK_10_7_Wreg & TOK_10_7_Breg
  { export TOK_10_7_Breg; }

Wndb_t:    TOK_3_0_Wreg                         is TOK_3_0_Wreg
  { export TOK_3_0_Wreg; }

Wndbyte_t: TOK_3_0_Wreg                         is TOK_3_0_Wreg & TOK_3_0_Breg
  { export TOK_3_0_Breg; }

Wns_t:     TOK_3_0_Wreg                         is TOK_3_0_Wreg
  { export TOK_3_0_Wreg; }

Wnsbyte_t: TOK_3_0_Wreg                         is TOK_3_0_Wreg & TOK_3_0_Breg
  { export TOK_3_0_Breg; }

Wb_t:      TOK_18_15_Wreg                       is TOK_18_15_Wreg
  { export TOK_18_15_Wreg; }

Wbbyte_t:  TOK_18_15_Wreg                       is TOK_18_15_Wreg & TOK_18_15_Breg
  { export TOK_18_15_Breg; }

Wbb_t:     TOK_14_11_Wreg                       is TOK_14_11_Wreg
  { export TOK_14_11_Wreg; }

Wbds_t:     TOK_14_12_Dregn                     is TOK_14_12_Dreg & TOK_14_12_Dregn
  { export TOK_14_12_Dreg; }

Wbbbyte_t: TOK_14_11_Wreg                       is TOK_14_11_Wreg & TOK_14_11_Breg
  { export TOK_14_11_Breg; }

Wnb_t:     TOK_3_0_Wreg                         is TOK_3_0_Wreg
  { export TOK_3_0_Wreg; }

Wnbbyte_t: TOK_3_0_Wreg                         is TOK_3_0_Wreg & TOK_3_0_Breg
  { export TOK_3_0_Breg; }

Wbd_t:     TOK_14_11_Wreg                       is TOK_14_11_Wreg 
  { export TOK_14_11_Wreg; }

WREG_t:    ",wreg"                            is TOK_B=0 & TOK_D=0
  { export W0; }

WREG_t:    ""                                 is TOK_B=0 & TOK_D=1 & TOK_f13
  { export *[ram]:2 TOK_f13; }

WREGbyte_t: ",wreg"                           is TOK_B=1 & TOK_D=0
  { export W0byte; }

WREGbyte_t: ""                                is TOK_B=1 & TOK_D=1 & TOK_f13
  { export *[ram]:1 TOK_f13; }

WREGb_t:    "wreg"                            is TOK_B=0 & TOK_D=0
  { export W0; }

WREGbbyte_t: "wreg"                           is TOK_B=1 & TOK_D=0
  { export W0byte; }

WREG_W0_t:    "wreg"                          is TOK_B=0 
  { export W0; }

WREG_W0byte_t: "wreg"                         is TOK_B=1 
  { export W0byte; }

f13b_t:     TOK_f13                           is TOK_B=0 & TOK_D=1 & TOK_f13
  { export *[ram]:2 TOK_f13; }

f13bbyte_t: TOK_f13                           is TOK_B=1 & TOK_D=1 & TOK_f13
  { export *[ram]:1 TOK_f13; }

f12_t:      val                           	  is TOK_f12 [ val = TOK_f12 << 1; ]
  { export *[ram]:2 val; }

f13_t:      TOK_f13                           is TOK_B=0 & TOK_f13
  { export *[ram]:2 TOK_f13; }

f13byte_t:  TOK_f13                           is TOK_B=1 & TOK_f13
  { export *[ram]:1 TOK_f13; }

f15_t:      addr                              is TOK_f15
  [ addr = ( TOK_f15 << 1 ); ] { export *[ram]:2 addr; }

f15b_t:      addr                             is TOK_f15b
  [ addr = ( TOK_f15b << 1 ); ] { export *[ram]:2 addr; }

k3_t:       "#"TOK_k3                         is TOK_k3
  { export *[const]:1 TOK_k3; }
  
k4_t:       "#"TOK_k4                         is TOK_k4
  { export *[const]:1 TOK_k4; }

k5:        "#"TOK_k5                          is TOK_k5
  { export *[const]:2 TOK_k5; }
  
k5_t:       "#"TOK_k5                         is TOK_B=0 & TOK_k5
  { export *[const]:2 TOK_k5; }

k5byte_t:   "#"TOK_k5                         is TOK_B=1 & TOK_k5
  { export *[const]:1 TOK_k5; }

k5_B10_t:       "#"TOK_k5                     is TOK_Bb=0 & TOK_k5
  { export *[const]:2 TOK_k5; }

k5byte_B10_t:   "#"TOK_k5                     is TOK_Bb=1 & TOK_k5
  { export *[const]:1 TOK_k5; }


k10_t:      "#"TOK_k10                        is TOK_B=0 & TOK_k10
  { export *[const]:2 TOK_k10; }

k10byte_t:  "#"TOK_k10                        is TOK_B=1 & TOK_13_12_xx=0 & TOK_k10
  { export *[const]:1 TOK_k10; }

k13_12_t: "#"TOK_13_12_kk                     is TOK_13_12_kk
  { export *[const]:1 TOK_13_12_kk; }
  
k14_t:      "#"TOK_k14                        is TOK_k14
  { export *[const]:2 TOK_k14; }

k15_t:      "#"TOK_k15                        is TOK_k15
  { export *[const]:2 TOK_k15; }
  
k16_t:      "#"TOK_k16                        is TOK_k16
  { export *[const]:2 TOK_k16; }

bit4_t:     "#"bit4                           is TOK_b3 & TOK_b1  [ bit4 = (TOK_b1 << 3) | TOK_b3; ] 
  { export *[const]:1 bit4; }

bit4byte_t: ".w"                              is TOK_bit4word=1  {  } #display only

bit4byte_t: ".b"                              is TOK_bit4word=0  {  } #display only

Bbit4_t:     "#"TOK_b4                        is TOK_b4
  { export *[const]:1 TOK_b4; }

n15_t:     TOK_n15 is TOK_n15       { export  *:3 TOK_n15; }
n16_t:     dest is TOK_n16          [ dest = inst_next + ( TOK_n16 << 1 ); ]            { export *:3 dest; }
dest24_t:  dest is TOK_n15 ; TOK_n7 [ dest = (( TOK_n7 << 16 ) $or ( TOK_n15 << 1 )); ] { export *:3 dest; }

WordInstNext: winstNext  is epsilon [ winstNext = inst_next + 0; ] { export *[const]:3 winstNext; }
WordInstNext4: winstNext  is epsilon [ winstNext = inst_next + 0; ] { export *[const]:4 winstNext; }

WnDest_t:   TOK_3_0_Wreg is TOK_3_0_Wreg                      { dest:3 = zext(TOK_3_0_Wreg & 0xFFFE); export dest; }
WnRDest_t:  TOK_3_0_Wreg is TOK_3_0_Wreg                      { dest:3 = 2 * zext(TOK_3_0_Wreg); export dest; }


# *2
WsSlit10_t: "["TOK_3_0_Wreg"+"val"]" is TOK_18_15_S & TOK_13_11_U & TOK_6_4_U & TOK_3_0_Wreg
  [ val = ((TOK_18_15_S << 6) $or (TOK_13_11_U << 3) $or TOK_6_4_U) << 1; ]
  { tmp:2 = (TOK_3_0_Wreg + val); export *[ram]:2 tmp; } 

WsSlit10byte_t: "["TOK_3_0_Wreg"+"val"]" is TOK_18_15_S & TOK_13_11_U & TOK_6_4_U & TOK_3_0_Wreg
  [ val = (TOK_18_15_S << 6) $or (TOK_13_11_U << 3) $or TOK_6_4_U; ]
  { tmp:2 = (TOK_3_0_Wreg + val); export *[ram]:1 tmp; }

# *2
WdSlit10_t: "["TOK_10_7_Wreg"+"val"]" is TOK_18_15_S & TOK_13_11_U & TOK_10_7_Wreg & TOK_6_4_U
  [ val = ((TOK_18_15_S << 6) $or (TOK_13_11_U << 3) $or TOK_6_4_U) << 1; ]
  { tmp:2 = (TOK_10_7_Wreg + val); export *[ram]:2 tmp; }  

WdSlit10byte_t: "["TOK_10_7_Wreg"+"val"]" is TOK_18_15_S & TOK_13_11_U & TOK_10_7_Wreg & TOK_6_4_U
  [ val = (TOK_18_15_S << 6) $or (TOK_13_11_U << 3) $or TOK_6_4_U; ]
  { tmp:2 = (TOK_10_7_Wreg + val); export *[ram]:1 tmp; }


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
n6_t:      dest     is TOK_n6            [ dest = inst_next + ( 2 * TOK_n6 ); ]
  { export *:3 dest; }

k8_t:       "#"k8   is TOK_k8b & TOK_k8a [ k8 = (TOK_k8b << 5) | TOK_k8a; ] 
  { export *[const]:2 k8; }
  
k8byte_t:       "#"k8   is TOK_k8b & TOK_k8a [ k8 = (TOK_k8b << 5) | TOK_k8a; ] 
  { export *[const]:1 k8; }

WnWn1_t:   TOK_3_0_Wreg is TOK_3_0_Wreg & TOK_14_11_Wreg
  { dest:3 = ( ( zext( TOK_14_11_Wreg & 0x007F ) << 16 ) | zext( TOK_3_0_Wreg & 0xFFFE ) ); export *:3 dest; }
@endif



@if defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) || defined(dsPIC33C)
Wbsft_t:      TOK_3_0_Wreg                      is TOK_3_0_Wreg
  { export TOK_3_0_Wreg; }

ACCA_t:      ACCA                             is TOK_A=0 & ACCA
  { export ACCA; } 

ACCB_t:      ACCB                             is TOK_A=1 & ACCB
  { export ACCB; }


r4_t:                                    	is TOK_r4 & OP_10_7=0
  { export *[const]:1 TOK_r4; }

r4_t:       ",#"TOK_r4                        is TOK_r4
  { export *[const]:1 TOK_r4; }

k6_t:       "#"TOK_k6                         is TOK_k6
  { export *[const]:1 TOK_k6; }



WsWRO_t: TOK_3_0_Wreg                           is TOK_6_4_U=0x0 & TOK_3_0_Wreg
  { export TOK_3_0_Wreg; }

WsWRO_t: "["TOK_3_0_Wreg"]"                     is TOK_6_4_U=0x1 & TOK_3_0_Wreg
  { export *[ram]:2 TOK_3_0_Wreg; }

WsWRO_t: "["TOK_3_0_Wreg"--]"                   is TOK_6_4_U=0x2 & TOK_3_0_Wreg
  { tmp:2 =  TOK_3_0_Wreg; TOK_3_0_Wreg = TOK_3_0_Wreg - 2; export *[ram]:2 tmp; }

WsWRO_t: "["TOK_3_0_Wreg"++]"                   is TOK_6_4_U=0x3 & TOK_3_0_Wreg
  { tmp:2 =  TOK_3_0_Wreg; TOK_3_0_Wreg = TOK_3_0_Wreg + 2; export *[ram]:2 tmp; }

WsWRO_t: "[--"TOK_3_0_Wreg"]"                   is TOK_6_4_U=0x4 & TOK_3_0_Wreg
  { TOK_3_0_Wreg = TOK_3_0_Wreg - 2; export *[ram]:2 TOK_3_0_Wreg; }

WsWRO_t: "[++"TOK_3_0_Wreg"]"                   is TOK_6_4_U=0x5 & TOK_3_0_Wreg
  { TOK_3_0_Wreg = TOK_3_0_Wreg + 2; export *[ram]:2 TOK_3_0_Wreg; }

WsWRO_t: "["TOK_3_0_Wreg"+"TOK_18_15_Wreg"]"    is TOK_6_4_U=0x6 & TOK_18_15_Wreg & TOK_3_0_Wreg
  { tmp:2 =  (TOK_3_0_Wreg + TOK_18_15_Wreg); export *[ram]:2 tmp; }

WsWRO_t: "["TOK_3_0_Wreg"+"TOK_18_15_Wreg"]"    is TOK_6_4_U=0x7 & TOK_18_15_Wreg & TOK_3_0_Wreg
  { tmp:2 =  (TOK_3_0_Wreg + TOK_18_15_Wreg); export *[ram]:2 tmp; }


WdWRO_t: TOK_3_0_Wreg                           is TOK_6_4_U=0x0 & TOK_3_0_Wreg
  { export TOK_3_0_Wreg; }

WdWRO_t: "["TOK_3_0_Wreg"]"                     is TOK_6_4_U=0x1 & TOK_3_0_Wreg
  { export *[ram]:2 TOK_3_0_Wreg; }

WdWRO_t: "["TOK_3_0_Wreg"--]"                   is TOK_6_4_U=0x2 & TOK_3_0_Wreg
  { tmp:2 =  TOK_3_0_Wreg; TOK_3_0_Wreg = TOK_3_0_Wreg - 2; export *[ram]:2 tmp; }

WdWRO_t: "["TOK_3_0_Wreg"++]"                   is TOK_6_4_U=0x3 & TOK_3_0_Wreg
  { tmp:2 =  TOK_3_0_Wreg; TOK_3_0_Wreg = TOK_3_0_Wreg + 2; export *[ram]:2 tmp; }

WdWRO_t: "[--"TOK_3_0_Wreg"]"                   is TOK_6_4_U=0x4 & TOK_3_0_Wreg
  { TOK_3_0_Wreg = TOK_3_0_Wreg - 2; export *[ram]:2 TOK_3_0_Wreg; }

WdWRO_t: "[++"TOK_3_0_Wreg"]"                   is TOK_6_4_U=0x5 & TOK_3_0_Wreg
  { TOK_3_0_Wreg = TOK_3_0_Wreg + 2; export *[ram]:2 TOK_3_0_Wreg; }

WdWRO_t: "["TOK_3_0_Wreg"+"TOK_18_15_Wreg"]"      is TOK_6_4_U=0x6 & TOK_18_15_Wreg & TOK_3_0_Wreg
  { tmp:2 = (TOK_3_0_Wreg + TOK_18_15_Wreg); export *[ram]:2 tmp; }

WdWRO_t: "["TOK_3_0_Wreg"+"TOK_18_15_Wreg"]"      is TOK_6_4_U=0x7 & TOK_18_15_Wreg & TOK_3_0_Wreg
  { tmp:2 = (TOK_3_0_Wreg + TOK_18_15_Wreg); export *[ram]:2  tmp; }




Wx_t: ",["W8"],"                        is TOK_9_6_iiii=0x0 & W8
  { export *[ram]:2 W8; }

Wx_t: ",["W8"]+=2,"                     is TOK_9_6_iiii=0x1 & W8
  { tmp:2 =  W8; W8 = W8 + 2; export *[ram]:2 tmp; }

Wx_t: ",["W8"]+=4,"                     is TOK_9_6_iiii=0x2 & W8
  { tmp:2 =  W8; W8 = W8 + 4; export *[ram]:2 tmp; }

Wx_t: ",["W8"]+=6,"                     is TOK_9_6_iiii=0x3 & W8
  { tmp:2 =  W8; W8 = W8 + 6; export *[ram]:2 tmp; }

Wx_t: ""                                is TOK_9_6_iiii=0x4      # No Prefetch for X Data Space
  { tmp:2 = 0; export tmp; }

Wx_t: ",["W8"]-=6,"                     is TOK_9_6_iiii=0x5 & W8
  { tmp:2 =  W8; W8 = W8 - 6; export *[ram]:2 tmp; }

Wx_t: ",["W8"]-=4,"                     is TOK_9_6_iiii=0x6 & W8
  { tmp:2 =  W8; W8 = W8 - 4; export *[ram]:2 tmp; }

Wx_t: ",["W8"]-=2,"                     is TOK_9_6_iiii=0x7 & W8
  { tmp:2 =  W8; W8 = W8 - 2; export *[ram]:2 tmp; }

Wx_t: ",["W9"],"                        is TOK_9_6_iiii=0x8 & W9
  { export *[ram]:2 W9; }

Wx_t: ",["W9"]+=2,"                     is TOK_9_6_iiii=0x9 & W9
  { tmp:2 =  W9; W9 = W9 + 2; export *[ram]:2 tmp; }

Wx_t: ",["W9"]+=4,"                     is TOK_9_6_iiii=0xA & W9
  { tmp:2 =  W9; W9 = W9 + 4; export *[ram]:2 tmp; }

Wx_t: ",["W9"]+=6,"                     is TOK_9_6_iiii=0xB & W9
  { tmp:2 =  W9; W9 = W9 + 6; export *[ram]:2 tmp; }

Wx_t: ",["W9"+"W12"],"                  is TOK_9_6_iiii=0xC & W9 & W12
  { tmp:2 =  (W9 + W12);      export *[ram]:2 tmp; }

Wx_t: ",["W9"]-=6,"                     is TOK_9_6_iiii=0xD & W9
  { tmp:2 =  W9; W9 = W9 - 6; export *[ram]:2 tmp; }

Wx_t: ",["W9"]-=4,"                     is TOK_9_6_iiii=0xE & W9
  { tmp:2 =  W9; W9 = W9 - 4; export *[ram]:2 tmp; }

Wx_t: ",["W9"]-=2,"                     is TOK_9_6_iiii=0xF & W9
  { tmp:2 =  W9; W9 = W9 - 2; export *[ram]:2 tmp; }



Wxd_t: ","W4                        is TOK_13_12_xx=0x0 & W4
  { export W4; }

Wxd_t: ","W5                        is TOK_13_12_xx=0x1 & W5
  { export W5; }

Wxd_t: ","W6                        is TOK_13_12_xx=0x2 & W6
  { export W6; }

Wxd_t: ","W7                        is TOK_13_12_xx=0x3 & W7
  { export W7; }



Wy_t: ",["W10"],"                        is TOK_5_2_jjjj=0x0 & W10
  { export *[ram]:2 W10; }

Wy_t: ",["W10"]+=2,"                     is TOK_5_2_jjjj=0x1 & W10
  { tmp:2 =  W10; W10 = W10 + 2; export *[ram]:2 tmp; }

Wy_t: ",["W10"]+=4,"                     is TOK_5_2_jjjj=0x2 & W10
  { tmp:2 =  W10; W10 = W10 + 4; export *[ram]:2 tmp; }

Wy_t: ",["W10"]+=6,"                     is TOK_5_2_jjjj=0x3 & W10
  { tmp:2 =  W10; W10 = W10 + 6; export *[ram]:2 tmp; }

Wy_t: ""                                 is TOK_5_2_jjjj=0x4      # No Prefetch for Y Data Space
  { tmp:2 = 0; export tmp; }

Wy_t: ",["W10"]-=6,"                     is TOK_5_2_jjjj=0x5 & W10
  { tmp:2 =  W10; W10 = W10 - 6; export *[ram]:2 tmp; }

Wy_t: ",["W10"]-=4,"                     is TOK_5_2_jjjj=0x6 & W10
  { tmp:2 =  W10; W10 = W10 - 4; export *[ram]:2 tmp; }

Wy_t: ",["W10"]-=2,"                     is TOK_5_2_jjjj=0x7 & W10
  { tmp:2 =  W10; W10 = W10 - 2; export *[ram]:2 tmp; }

Wy_t: ",["W11"]"                         is TOK_5_2_jjjj=0x8 & W11
  { export *[ram]:2 W11; }

Wy_t: ",["W11"]+=2,"                     is TOK_5_2_jjjj=0x9 & W11
  { tmp:2 =  W11; W11 = W11 + 2; export *[ram]:2 tmp; }

Wy_t: ",["W11"]+=4,"                     is TOK_5_2_jjjj=0xA & W11
  { tmp:2 =  W11; W11 = W11 + 4; export *[ram]:2 tmp; }

Wy_t: ",["W11"]+=6,"                     is TOK_5_2_jjjj=0xB & W11
  { tmp:2 =  W11; W11 = W11 + 6; export *[ram]:2 tmp; }

Wy_t: ",["W11"+"W12"],"                  is TOK_5_2_jjjj=0xC & W11 & W12
  { tmp:2 =  (W11 + W12);        export *[ram]:2 tmp; }

Wy_t: ",["W11"]-=6,"                     is TOK_5_2_jjjj=0xD & W11
  { tmp:2 =  W11; W11 = W11 - 6; export *[ram]:2 tmp; }

Wy_t: ",["W11"]-=4,"                     is TOK_5_2_jjjj=0xE & W11
  { tmp:2 =  W11; W11 = W11 - 4; export *[ram]:2 tmp; }

Wy_t: ",["W11"]-=2,"                     is TOK_5_2_jjjj=0xF & W11
  { tmp:2 =  W11; W11 = W11 - 2; export *[ram]:2 tmp; }



WmWm_t: W4"*W4"                  is TOK_17_16_mm=0x0 & W4
  { tmp:6 = (sext(W4) * sext(W4)); export tmp; }

WmWm_t: W5"*W5"                  is TOK_17_16_mm=0x1 & W5
  { tmp:6 = (sext(W5) * sext(W5)); export tmp; }

WmWm_t: W6"*W6"                  is TOK_17_16_mm=0x2 & W6
  { tmp:6 = (sext(W6) * sext(W6)); export tmp; }

WmWm_t: W7"*W7"                  is TOK_17_16_mm=0x3 & W7
  { tmp:6 = (sext(W7) * sext(W7)); export tmp; }



WmWn_t: W4"*"W5                  is TOK_18_16_mmm=0x0 & W4 & W5
  { tmp:6 = (sext(W4) * sext(W5)); export tmp; }

WmWn_t: W4"*"W6                  is TOK_18_16_mmm=0x1 & W4 & W6
  { tmp:6 = (sext(W4) * sext(W6)); export tmp; }

WmWn_t: W4"*"W7                  is TOK_18_16_mmm=0x2 & W4 & W7
  { tmp:6 = (sext(W4) * sext(W7)); export tmp; }

WmWn_t: "invalid"                is TOK_18_16_mmm=0x3
  { tmp:6 = 0; export tmp; }

WmWn_t: W5"*"W6                  is TOK_18_16_mmm=0x4 & W5 & W6
  { tmp:6 = (sext(W5) * sext(W6)); export tmp; }

WmWn_t: W5"*"W7                  is TOK_18_16_mmm=0x5 & W5 & W7
  { tmp:6 = (sext(W5) * sext(W7)); export tmp; }

WmWn_t: W6"*"W7                  is TOK_18_16_mmm=0x6 & W6 & W7
  { tmp:6 = (sext(W6) * sext(W7)); export tmp; }

WmWn_t: "invalid"                is TOK_18_16_mmm=0x7
  { tmp:6 = 0; export tmp; }



Wyd_t: ","W4                        is TOK_11_10_yy=0x0 & W4
  { export W4; }

Wyd_t: ","W5                        is TOK_11_10_yy=0x1 & W5
  { export W5; }

Wyd_t: ","W6                        is TOK_11_10_yy=0x2 & W6
  { export W6; }

Wyd_t: ","W7                        is TOK_11_10_yy=0x3 & W7
  { export W7; }


AWB_t: ","W13                           is TOK_1_0_aa=0x0 & W13
  { export W13; }

AWB_t: ",["W13"]+=2"                    is TOK_1_0_aa=0x1 & W13
  { tmp:2 =  W13; W13 = W13 + 2; export *[ram]:2 tmp; }

AWB_t: ""                               is TOK_1_0_aa=0x2        # No write back
  { tmp:2 = 0; export tmp; }

AWB_t: ",invalid"                       is TOK_1_0_aa=0x3        # invalid
  { tmp:2 = 0; export tmp; }
@endif


# Use must be constrained by $(WSconstraint)
WsMUL_t: TOK_3_0_Wreg                           is TOK_6_4_U=0x0 & TOK_3_0_Wreg
  { export TOK_3_0_Wreg; }

WsMUL_t: "["TOK_3_0_Wreg"]"                     is TOK_6_4_U=0x1 & TOK_3_0_Wreg
  { export *[ram]:2 TOK_3_0_Wreg; }

WsMUL_t: "["TOK_3_0_Wreg"--]"                   is TOK_6_4_U=0x2 & TOK_3_0_Wreg
  { tmp:2 =  TOK_3_0_Wreg; TOK_3_0_Wreg = TOK_3_0_Wreg - 2; export *[ram]:2 tmp; }

WsMUL_t: "["TOK_3_0_Wreg"++]"                   is TOK_6_4_U=0x3 & TOK_3_0_Wreg
  { tmp:2 =  TOK_3_0_Wreg; TOK_3_0_Wreg = TOK_3_0_Wreg + 2; export *[ram]:2 tmp; }

WsMUL_t: "[--"TOK_3_0_Wreg"]"                   is TOK_6_4_U=0x4 & TOK_3_0_Wreg
  { TOK_3_0_Wreg = TOK_3_0_Wreg - 2; export *[ram]:2 TOK_3_0_Wreg; }

WsMUL_t: "[++"TOK_3_0_Wreg"]"                   is TOK_6_4_U=0x5 & TOK_3_0_Wreg
  { TOK_3_0_Wreg = TOK_3_0_Wreg + 2; export *[ram]:2 TOK_3_0_Wreg; }



# Use must be constrained by $(WDconstraint)
WdMUL_t: TOK_10_7_Wreg                           is TOK_13_11_U=0x0 & TOK_10_7_Wreg
  { export TOK_10_7_Wreg; }

WdMUL_t: "["TOK_10_7_Wreg"]"                     is TOK_13_11_U=0x1 & TOK_10_7_Wreg
  { export *[ram]:2 TOK_10_7_Wreg; }

WdMUL_t: "["TOK_10_7_Wreg"--]"                   is TOK_13_11_U=0x2 & TOK_10_7_Wreg
  { tmp:2 =  TOK_10_7_Wreg; TOK_10_7_Wreg = TOK_10_7_Wreg - 2; export *[ram]:2 tmp; }

WdMUL_t: "["TOK_10_7_Wreg"++]"                   is TOK_13_11_U=0x3 & TOK_10_7_Wreg
  { tmp:2 =  TOK_10_7_Wreg; TOK_10_7_Wreg = TOK_10_7_Wreg + 2; export *[ram]:2 tmp; }

WdMUL_t: "[--"TOK_10_7_Wreg"]"                   is TOK_13_11_U=0x4 & TOK_10_7_Wreg
  { TOK_10_7_Wreg = TOK_10_7_Wreg - 2; export *[ram]:2 TOK_10_7_Wreg; }

WdMUL_t: "[++"TOK_10_7_Wreg"]"                   is TOK_13_11_U=0x5 & TOK_10_7_Wreg
  { TOK_10_7_Wreg = TOK_10_7_Wreg + 2; export *[ram]:2 TOK_10_7_Wreg; }


# Use must be constrained by $(WSconstraint)
WsROM_t: "["TOK_3_0_Wreg"]"                     is TOK_6_4_U=0x1 & TOK_3_0_Wreg
  { addr:3 = (zext(TBLPAG)<<16) | zext(TOK_3_0_Wreg); export addr; }

WsROM_t: "["TOK_3_0_Wreg"--]"                   is TOK_6_4_U=0x2 & TOK_3_0_Wreg
  { tmp:2 = TOK_3_0_Wreg; addr:3 = (zext(TBLPAG)<<16) | zext(tmp); TOK_3_0_Wreg = tmp - 2; export addr; }

WsROM_t: "["TOK_3_0_Wreg"++]"                   is TOK_6_4_U=0x3 & TOK_3_0_Wreg
  { tmp:2 = TOK_3_0_Wreg; addr:3 = (zext(TBLPAG)<<16) | zext(tmp); TOK_3_0_Wreg = tmp + 2; export addr; }

WsROM_t: "[--"TOK_3_0_Wreg"]"                   is TOK_6_4_U=0x4 & TOK_3_0_Wreg
  { tmp:2 = TOK_3_0_Wreg - 2; addr:3 = (zext(TBLPAG)<<16) | zext(tmp); TOK_3_0_Wreg = tmp; export addr; }

WsROM_t: "[++"TOK_3_0_Wreg"]"                   is TOK_6_4_U=0x5 & TOK_3_0_Wreg
  { tmp:2 = TOK_3_0_Wreg + 2; addr:3 = (zext(TBLPAG)<<16) | zext(tmp); TOK_3_0_Wreg = tmp; export addr; }


# Use must be constrained by $(WDconstraint)
WdROM_t: "["TOK_10_7_Wreg"]"                     is TOK_13_11_U=0x1 & TOK_10_7_Wreg
  { addr:3 = (zext(TBLPAG)<<16) | zext(TOK_10_7_Wreg); export addr; }

WdROM_t: "["TOK_10_7_Wreg"--]"                   is TOK_13_11_U=0x2 & TOK_10_7_Wreg
  { tmp:2 = TOK_10_7_Wreg; addr:3 = (zext(TBLPAG)<<16) | zext(tmp); TOK_10_7_Wreg = tmp - 2; export addr; }

WdROM_t: "["TOK_10_7_Wreg"++]"                   is TOK_13_11_U=0x3 & TOK_10_7_Wreg
  { tmp:2 = TOK_10_7_Wreg; addr:3 = (zext(TBLPAG)<<16) | zext(tmp); TOK_10_7_Wreg = tmp + 2; export addr; }

WdROM_t: "[--"TOK_10_7_Wreg"]"                   is TOK_13_11_U=0x4 & TOK_10_7_Wreg
  { tmp:2 = TOK_10_7_Wreg - 2; addr:3 = (zext(TBLPAG)<<16) | zext(tmp); TOK_10_7_Wreg = tmp; export addr; }

WdROM_t: "[++"TOK_10_7_Wreg"]"                   is TOK_13_11_U=0x5 & TOK_10_7_Wreg
  { tmp:2 = TOK_10_7_Wreg + 2; addr:3 = (zext(TBLPAG)<<16) | zext(tmp); TOK_10_7_Wreg = tmp; export addr; }


# Macros ==========================================================================

## 16-bit working register math flag support

# for decimal carry of a byte
macro testSRH_DCbyte(a) {
  SRH_DC = ( 0x10 & a ) != 0;
}

# for decimal carry of a word
macro testSRH_DCword(a) {
  SRH_DC = ( 0x100 & a ) != 0;
}

# for negative of a byte or word
macro testSRL_N(a) {
  SRL_N = (a s< 0);
}

# for (signed) addition of bytes or words: a + b
macro testSRL_OVadd(a,b) {
  SRL_OV = scarry(a,b);
}

# for (signed) addition of words with carry: a + b + c
macro testSRL_OVaddc(a,b,c) {
  tmp:4 	= sext(a) + sext(b) + zext(c);
  SRL_OV 	= (tmp s< -0x00008000) || (tmp s> 0x00007FFF);
}

# for (signed) addition of bytes with carry: a + b + c
macro testSRL_OVaddcByte(a,b,c) {
  tmp:2 	= sext(a) + sext(b) + zext(c);
  SRL_OV 	= (tmp s< -0x0080) || (tmp s> 0x007F);
}

# for (signed) subtraction of bytes or words: a - b
macro testSRL_OVsub(a,b) {
  SRL_OV = sborrow(a,b);
}

# for (signed) subtraction of words with carry: a - b - c
macro testSRL_OVsubc(a,b,c) {
  tmp:4 	= sext(a) - sext(b) - zext(c);
  SRL_OV	= (tmp s< -0x00008000) || (tmp s> 0x00007FFF);
}

# for (signed) subtraction of bytes with carry: a - b - c
macro testSRL_OVsubcByte(a,b,c) {
  tmp:2 	= sext(a) - sext(b) - zext(c);
  SRL_OV 	= (tmp s< -0x0080) || (tmp s> 0x007F);
}

# for zero of a byte or word
macro testSRL_Z(a) {
  SRL_Z = (a == 0);
}

# for zero sticky of a byte or word
macro testSRL_Zsticky(a) {
  SRL_Z = SRL_Z && (a == 0);
}

macro addflags(a,b) {
	SRL_C = carry(a,b);
	SRL_OV = scarry(a,b);
}

macro addflagsWithCarry(a,b,c) {
    local ab = a + b;
	SRL_C = carry(a,b) || carry(ab,c);
	SRL_OV = scarry(a,b) || scarry(ab,c);
}

macro subflags(a,b) {
	SRL_C = a >= b; # inverted for borrow
	SRL_OV = sborrow(a,b);
}

macro subflagsWithCarry(a,b,c) {
    local bc = b + c;
	SRL_C = (a >= b) && (a >= bc); # inverted for borrow
	SRL_OV = sborrow(a,b) || sborrow(a,bc); 
}


## 40-bit ACCA and ACCB register math flag support

# for addition (signed)
macro testSRH_OA() {
  SRH_OA 	= ( ACCA & 0xFFFF00000000 ) != 0;
  SRH_OAB 	= SRH_OA || SRH_OB;
}

# for addition (signed)
macro testSRH_OB() {
  SRH_OB 	= ( ACCB & 0xFFFF00000000 ) != 0;
  SRH_OAB 	= SRH_OA || SRH_OB;
}

# for addition (signed)
# Note: sticky bits
macro testSRH_SA() {
  SRH_SA	= SRH_SA | ( ( ACCA & 0x000100000000 ) != 0 );
  SRH_SAB 	= SRH_SAB | SRH_SA;
}

# for addition (signed)
# Note: sticky bits
macro testSRH_SB() {
  SRH_SB 	= SRH_SB | ( ( ACCB & 0x000100000000 ) != 0 );
  SRH_SAB 	= SRH_SAB | SRH_SB;
}


# 1000 0000
@define SRH_OAbit           "0x80"

# 0100 0000
@define SRH_OBbit           "0x40"

# 0010 0000
@define SRH_SAbit           "0x20"

# 0001 0000
@define SRH_SBbit           "0x10"

# 0000 1000
@define SRH_OABbit          "0x08"

# 0000 0100
@define SRH_SABbit          "0x04"

# 0000 0010
@define SRH_DAbit           "0x02"

# 0000 0001
@define SRH_DCbit           "0x01"


# SR component register fields (pseudo)
macro unpackSRH( unpackByte ) {
  SRH_OA  = ( $(SRH_OAbit)  & unpackByte ) != 0;
  SRH_OB  = ( $(SRH_OBbit)  & unpackByte ) != 0;
  SRH_SA  = ( $(SRH_SAbit)  & unpackByte ) != 0;
  SRH_SB  = ( $(SRH_SBbit)  & unpackByte ) != 0;
  SRH_OAB = ( $(SRH_OABbit) & unpackByte ) != 0;
  SRH_SAB = ( $(SRH_SABbit) & unpackByte ) != 0;
  SRH_DA  = ( $(SRH_DAbit)  & unpackByte ) != 0;
  SRH_DC  = ( $(SRH_DCbit)  & unpackByte ) != 0;
}


macro packSRH( packByte ) {
  packByte = (SRH_OA  * $(SRH_OAbit))  |
             (SRH_OB  * $(SRH_OBbit))  |
             (SRH_SA  * $(SRH_SAbit))  |
             (SRH_SB  * $(SRH_SBbit))  |
             (SRH_OAB * $(SRH_OABbit)) |
             (SRH_SAB * $(SRH_SABbit)) |
             (SRH_DA  * $(SRH_DAbit))  |
             (SRH_DC  * $(SRH_DCbit))  ;
}


# 1000 0000
@define SRL_IPL2bit           "0x80"

# 0100 0000
@define SRL_IPL1bit           "0x40"

# 0010 0000
@define SRL_IPL0bit           "0x20"

# 0001 0000
@define SRL_RAbit             "0x10"

# 0000 1000
@define SRL_Nbit              "0x08"

# 0000 0100
@define SRL_OVbit             "0x04"

# 0000 0010
@define SRL_Zbit              "0x02"

# 0000 0001
@define SRL_Cbit              "0x01"


macro unpackSRL( unpackByte ) {
  SRL_IPL2 = ( $(SRL_IPL2bit) & unpackByte ) != 0;
  SRL_IPL1 = ( $(SRL_IPL1bit) & unpackByte ) != 0;
  SRL_IPL0 = ( $(SRL_IPL0bit) & unpackByte ) != 0;
  SRL_RA   = ( $(SRL_RAbit)   & unpackByte ) != 0;
  SRL_N    = ( $(SRL_Nbit)    & unpackByte ) != 0;
  SRL_OV   = ( $(SRL_OVbit)   & unpackByte ) != 0;
  SRL_Z    = ( $(SRL_Zbit)    & unpackByte ) != 0;
  SRL_C    = ( $(SRL_Cbit)    & unpackByte ) != 0;
}


macro packSRL( packByte ) {
  packByte = (SRL_IPL2 * $(SRL_IPL2bit)) |
             (SRL_IPL1 * $(SRL_IPL1bit)) |
             (SRL_IPL0 * $(SRL_IPL0bit)) |
             (SRL_RA   * $(SRL_RAbit))   |
             (SRL_N    * $(SRL_Nbit))    |
             (SRL_OV   * $(SRL_OVbit))   |
             (SRL_Z    * $(SRL_Zbit))    |
             (SRL_C    * $(SRL_Cbit))    ;
}


# Constructors ====================================================================


@if defined(dsPIC30) || defined(dsPIC33F) || defined(dsPIC33E) || defined(dsPIC33C)
# The "blockEnd" is the flag to indicate where the goto to cause the loop must be inserted.
# Previously an :do instruction figured out the address it needed an goto to be inserted and do something like
# do: .... [ blockEnd=1; globalset(addressForGoto,blockEnd); ]  which will cause the context bit blockEnd to be
# set on the end of loop address.

# PHASE-0 Handle end-of-loop

getDOSTART: is epsilon { export *:3 DOSTART; }

:^instruction is phase=0 & blockEnd=1 & instruction & getDOSTART [ phase = 1; ] {

@if defined(dsPIC30F) || defined(dsPIC33F)
  DCOUNT         = DCOUNT - 1;
  if (DCOUNT != 0) goto getDOSTART;

  DCOUNT         = DCOUNT_SHADOW;
  DOEND          = DOEND_SHADOW;
  DOSTART        = DOSTART_SHADOW;
@endif
@if defined(dsPIC33E) || defined(dsPIC33C)
  DL:2                               = zext(CORCON_DL);
  *[register]:2 (&:2 DCOUNT  + DL*2) = (*[register]:2 (&:2 DCOUNT + DL*2)) - 1;	
  count:2                            =  *[register]:2 (&:2 DCOUNT + DL*2);
  if (count != 0)  goto getDOSTART;

  # stack 4 levels deep but we don't enforce this
  CORCON_DL      = CORCON_DL - 1;
@endif

}
@endif

:^instruction is phase=0 & instruction [ phase = 1; ] {
  build instruction;
}

# PHASE-1 Handle repeat / skip

:^instruction is phase=1 & repeatInstr=1 & instruction  [ phase = 2; ] {

  if (RCOUNT == 0) goto <done>;
  RCOUNT = RCOUNT - 1;
  build instruction;
  goto inst_start;
<done>
}



# TODO: Why is context/^instruction used instead of simply having skip instructions branch around next instruction? 

# skipNext global support:
:^instruction is phase=1 & skipInstr=1 & instruction  [ phase = 2; ] { 

  if ( SkipNextFlag == 1 ) goto <done>;
  build instruction;
<done>
}

:^instruction is phase=1 & instruction  [ phase = 2; ] {
  build instruction;
}



with : phase = 2 {

:add.w   f13_t^WREG_t is OP_23_20=0xB & OP_19_16=0x4 & OP_15=0 & WREG_t & f13_t {

  local src = f13_t;
  addflags( src,  W0 );

  local result =       src + W0;
  WREG_t = result;

  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCword( result );
}


:add.b f13byte_t^WREGbyte_t is OP_23_20=0xB & OP_19_16=0x4 & OP_15=0 & WREGbyte_t & f13byte_t {

  local src = f13byte_t;
  addflags( src,  W0byte );

  local result = src + W0byte;
  WREGbyte_t = result;

  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCbyte( result );
}


:add.w   k10_t,Wn_t is OP_23_20=0xB & OP_19_16=0x0 & OP_15=0 & k10_t & Wn_t {

  local src = k10_t;
  addflags( src,  Wn_t );

  local result = src + Wn_t;
  Wn_t = result;

  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCword( result );
} 


:add.b   k10byte_t,Wnbyte_t is OP_23_20=0xB & OP_19_16=0x0 & OP_15=0 & k10byte_t & Wnbyte_t {

  local src = k10byte_t;
  addflags( src,  Wnbyte_t );

  local result = src + Wnbyte_t;
  Wnbyte_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCbyte( result );
}


:add.w   Wb_t,k5_t,Wd_t is OP_23_20=0x4 & OP_19=0x0 & OP_6_5=0x3 & Wb_t & $(WDconstraint) & Wd_t & k5_t {

  addflags( k5_t,  Wb_t );

  local result =         k5_t + Wb_t;
  build Wd_t;
  Wd_t = result;

  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCword( result );
} 


:add.b  Wbbyte_t,k5byte_t,Wdbyte_t is
        OP_23_20=0x4 & OP_19=0x0 & OP_6_5=0x3 & Wbbyte_t & $(WDconstraint) & Wdbyte_t & k5byte_t {

  addflags( k5byte_t,  Wbbyte_t );

  local result =     k5byte_t + Wbbyte_t;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCbyte( result );
} 


:add.w   Wb_t,Ws_t,Wd_t is OP_23_20=0x4 & OP_19=0x0 & TOK_B=0 & Wb_t & $(WDconstraint) & Wd_t & $(WSconstraint) & Ws_t {

  local src = Ws_t;
  addflags( Wb_t, src );
  
  local result = Wb_t + src;
  build Wd_t;
  Wd_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCword( result );
}

:add.b  Wbbyte_t,Wsbyte_t,Wdbyte_t is OP_23_20=0x4 & OP_19=0x0 & TOK_B=1 & Wbbyte_t & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & Wsbyte_t {

  local src = Wsbyte_t;
  addflags( Wbbyte_t,  src );

  local result =     Wbbyte_t + src;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCbyte( result );
} 


@if defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) || defined(dsPIC33C)
:add ACCA_t is OP_23_20=0xC & OP_19_16=0xB & ACCA_t & OP_14_12=0x0 & OP_11_8=0x0 & OP_7_4=0x0 & OP_3_0=0x0 {

  ACCA = ACCA + ACCB;
  testSRH_OA();
  testSRH_SA();
} 

:add ACCB_t is OP_23_20=0xC & OP_19_16=0xB & ACCB_t & OP_14_12=0x0 & OP_11_8=0x0 & OP_7_4=0x0 & OP_3_0=0x0 {

  ACCB = ACCA + ACCB;
  testSRH_OB();
  testSRH_SB();
} 
@endif


@if defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) || defined(dsPIC33C)
:add WsWRO_t^r4_t,ACCA_t is OP_23_20=0xC & OP_19_16=0x9 & ACCA_t & r4_t & WsWRO_t {

  ACCA = (sext(WsWRO_t) << (16 - r4_t)) + ACCA;
  testSRH_OA();
  testSRH_SA();
} 

:add WsWRO_t^r4_t,ACCB_t is OP_23_20=0xC & OP_19_16=0x9 & ACCB_t & r4_t & WsWRO_t {

  ACCB = (sext(WsWRO_t) << (16 - r4_t)) + ACCB;
  testSRH_OB();
  testSRH_SB();
} 
@endif


:addc.w   f13_t^WREG_t is OP_23_20=0xB & OP_19_16=0x4 & OP_15=1 & WREG_t & f13_t {

  local c:2 = zext(SRL_C);
  local src = f13_t;
  addflagsWithCarry( src,  W0, c );

  local result = src + W0 + c;
  WREG_t = result;
  
  testSRL_N      ( result );
  testSRL_Zsticky( result );
  testSRH_DCword ( result );
} 

:addc.b f13byte_t^WREGbyte_t is OP_23_20=0xB & OP_19_16=0x4 & OP_15=1 & WREGbyte_t & f13byte_t {

  local c = SRL_C;
  local src = f13byte_t;
  addflagsWithCarry( src,  W0byte, c );

  local result = src + W0byte + c;
  WREGbyte_t = result;
  
  testSRL_N      ( result );
  testSRL_Zsticky( result );
  testSRH_DCbyte ( result );
}


:addc.w   k10_t,Wn_t is OP_23_20=0xB & OP_19_16=0x0 & OP_15=1 & k10_t & Wn_t {

  local c:2 = zext(SRL_C);
  addflagsWithCarry( k10_t,  Wn_t, c );

  Wn_t =          k10_t + Wn_t + c;

  testSRL_N      ( Wn_t );
  testSRL_Zsticky( Wn_t );
  testSRH_DCword ( Wn_t );
} 


:addc.b   k10byte_t,Wnbyte_t is OP_23_20=0xB & OP_19_16=0x0 & OP_15=1 & k10byte_t & Wnbyte_t {

  local c = SRL_C;
  addflagsWithCarry( k10byte_t,  Wnbyte_t, c );

  Wnbyte_t =          k10byte_t + Wnbyte_t + c;

  testSRL_N      ( Wnbyte_t );
  testSRL_Zsticky( Wnbyte_t );
  testSRH_DCbyte ( Wnbyte_t );
}


:addc.w   Wb_t,k5_t,Wd_t is OP_23_20=0x4 & OP_19=0x1 & OP_6_5=0x3 & Wb_t & $(WDconstraint) & Wd_t & k5_t {

  local c:2 = zext(SRL_C);
  addflagsWithCarry( k5_t,  Wb_t, c );

  local result =          k5_t + Wb_t + c;
  build Wd_t;
  Wd_t = result;
  
  testSRL_N      ( result );
  testSRL_Zsticky( result );
  testSRH_DCword ( result );
} 


:addc.b  Wbbyte_t,k5byte_t,Wdbyte_t is
         OP_23_20=0x4 & OP_19=0x1 & OP_6_5=0x3 & Wbbyte_t & $(WDconstraint) & Wdbyte_t & k5byte_t {

  local c = SRL_C;
  addflagsWithCarry( k5byte_t,  Wbbyte_t, c );

  local result =          k5byte_t + Wbbyte_t + c;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N      ( result );
  testSRL_Zsticky( result );
  testSRH_DCbyte ( result );
} 


:addc.w   Wb_t,Ws_t,Wd_t is OP_23_20=0x4 & OP_19=0x1 & TOK_B=0 & Wb_t & $(WDconstraint) & Wd_t & $(WSconstraint) & Ws_t {

  local c:2 = zext(SRL_C);
  local src = Ws_t;
  addflagsWithCarry( Wb_t,  src, c );

  local result = Wb_t + src + c;
  build Wd_t;
  Wd_t = result;
  
  testSRL_N      ( result );
  testSRL_Zsticky( result );
  testSRH_DCword ( result );
} 


:addc.b  Wbbyte_t,Wsbyte_t,Wdbyte_t is OP_23_20=0x4 & OP_19=0x1 & TOK_B=1 & Wbbyte_t & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & Wsbyte_t {

  local c = SRL_C;
  local src = Wsbyte_t;
  addflagsWithCarry( Wbbyte_t,  src, c );

  local result = Wbbyte_t + src + c;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N      ( result );
  testSRL_Zsticky( result );
  testSRH_DCbyte ( result );
} 


:and.w   f13_t^WREG_t is OP_23_20=0xB & OP_19_16=0x6 & OP_15=0 & WREG_t & f13_t {

  WREG_t =       f13_t & W0;

  testSRL_N     ( WREG_t );
  testSRL_Z     ( WREG_t );
} 


:and.b f13byte_t^WREGbyte_t is OP_23_20=0xB & OP_19_16=0x6 & OP_15=0 & WREGbyte_t & f13byte_t {

  WREGbyte_t =   f13byte_t & W0byte;

  testSRL_N     ( WREGbyte_t );
  testSRL_Z     ( WREGbyte_t );
}


:and.w   k10_t,Wn_t is OP_23_20=0xB & OP_19_16=0x2 & OP_15=0 & k10_t & Wn_t {

  Wn_t =         k10_t & Wn_t;

  testSRL_N     ( Wn_t );
  testSRL_Z     ( Wn_t );
} 


:and.b   k10byte_t,Wnbyte_t is OP_23_20=0xB & OP_19_16=0x2 & OP_15=0 & k10byte_t & Wnbyte_t {

  Wnbyte_t =     k10byte_t & Wnbyte_t;

  testSRL_N     ( Wnbyte_t );
  testSRL_Z     ( Wnbyte_t );
}


:and.w   Wb_t,k5_t,Wd_t is OP_23_20=0x6 & OP_19=0x0 & OP_6_5=0x3 & Wb_t & $(WDconstraint) & Wd_t & k5_t {

  local result =         k5_t & Wb_t;
  Wd_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
} 


:and.b  Wbbyte_t,k5byte_t,Wdbyte_t is
        OP_23_20=0x6 & OP_19=0x0 & OP_6_5=0x3 & Wbbyte_t & $(WDconstraint) & Wdbyte_t & k5byte_t {

  local result =     k5byte_t & Wbbyte_t;
  Wdbyte_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
} 


:and.w   Wb_t,Ws_t,Wd_t is OP_23_20=0x6 & OP_19=0x0 & TOK_B=0 & Wb_t & $(WDconstraint) & Wd_t & $(WSconstraint) & Ws_t {

  local result = Wb_t & Ws_t;
  build Wd_t;
  Wd_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
} 


:and.b  Wbbyte_t,Wsbyte_t,Wdbyte_t is OP_23_20=0x6 & OP_19=0x0 & TOK_B=1 & Wbbyte_t & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & Wsbyte_t {

  local result = Wbbyte_t & Wsbyte_t;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
} 


:asr.w   f13_t^WREG_t is OP_23_20=0xD & OP_19_16=0x5 & OP_15=1 & WREG_t & f13_t {

  local src = f13_t;
  SRL_C  =       ( src & 1 ) != 0;
  WREG_t =         src s>> 1;

  testSRL_N     ( WREG_t );
  testSRL_Z     ( WREG_t );
} 


:asr.b f13byte_t^WREGbyte_t is OP_23_20=0xD & OP_19_16=0x5 & OP_15=1 & WREGbyte_t & f13byte_t {

  local src = f13byte_t;
  SRL_C  =       ( src & 1 ) != 0;
  WREGbyte_t =     src s>> 1;

  testSRL_N     ( WREGbyte_t );
  testSRL_Z     ( WREGbyte_t );
}


:asr.w   Ws_t,Wd_t is OP_23_20=0xD & OP_19_16=0x1 & OP_15=0x1 & TOK_B=0 & $(WDconstraint) & Wd_t & $(WSconstraint) & Ws_t {

  local src = Ws_t;
  
  SRL_C = ( src & 1 ) != 0;
  local result  =   src s>> 1;
  build Wd_t;
  Wd_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
} 


:asr.b  Wsbyte_t,Wdbyte_t is OP_23_20=0xD & OP_19_16=0x1 & OP_15=0x1 & TOK_B=1 & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & Wsbyte_t {

  local src = Wsbyte_t;
  
  SRL_C     = ( src & 1 ) != 0;
  local result  =   src s>> 1;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
} 


:asr.w   Wbd_t,k4_t,Wnd_t is OP_23_20=0xD & OP_19_16=0xE & OP_15=0x1 & OP_6_4=0x4 & Wbd_t & Wnd_t & k4_t {

  Wnd_t = Wbd_t s>> k4_t;

  testSRL_N     ( Wnd_t );
  testSRL_Z     ( Wnd_t );
} 


:asr.w  Wbd_t,Wns_t,Wnd_t is OP_23_20=0xD & OP_19_16=0xE & OP_15=0x1 & OP_6_4=0x0 & Wbd_t & Wnd_t & Wns_t {

  Wnd_t = Wbd_t s>> ( Wns_t & 0x001F );

  testSRL_N     ( Wnd_t );
  testSRL_Z     ( Wnd_t );
} 


# The pdf manual is very confusing for this instruction. The final conclusion is that the .B
# is really a pseudo instruction and that everything is actually encoded as a word with the
# 'f' bits being left shifted by 1
:bclr.w  f12_t,bit4_t is OP_23_20=0xA & OP_19_16=0x9 & bit4_t & f12_t {

  local mask:2 = ~(1 << bit4_t);
  f12_t = f12_t & mask;
} 


# DSRPAG ????? 
:bclr.w  Wsb_t,Bbit4_t is
  OP_23_20=0xA & OP_19_16=0x1 & Bbit4_t & OP_11=0x0 & TOK_Bb=0 & OP_9_8=0x0 & OP_7=0x0 & $(WSconstraint) & Wsb_t {

  local mask:2 = ~(1 << Bbit4_t);
  Wsb_t = Wsb_t & mask;
} 


:bclr.b  Wsbbyte_t,Bbit4_t is
  OP_23_20=0xA & OP_19_16=0x1 & Bbit4_t & OP_11=0x0 & TOK_Bb=1 & OP_9_8=0x0 & OP_7=0x0 & $(WSconstraint) & Wsbbyte_t {

  local mask:1 = ~(1 << Bbit4_t);
  Wsbbyte_t = Wsbbyte_t & mask;
} 


@if defined(dsPIC33C)
:bfext TOK_k4 "#"wid5, Wsb_t, Wnbf_t is
	OP_23_16=0x0A & OP_15_12=0x8 & Wnbf_t & TOK_k4b & TOK_k4;
	OP_23_16=0x0 & OP_15_8=0x0 & OP_7=0x0 & Wsb_t
[wid5 = TOK_k4b - TOK_k4 + 1;]
{
    local mask:2 = (0xff >> (16-(wid5 + 1))) << TOK_k4;
    local result:2 = (Wsb_t & mask) >> TOK_k4;
	Wnbf_t = result;
}

:bfext TOK_k4 "#"wid5, n15_t, Wnbf_t is
	OP_23_16=0x0A & OP_15_12=0xA & Wnbf_t & TOK_k4b & TOK_k4;
	OP_23_16=0x0 & OP_0=0x0 & n15_t
[wid5 = TOK_k4b - TOK_k4 + 1;]
{
    local mask:2 = (0xff >> (16-(wid5 + 1))) << TOK_k4;
    local word = *:2 n15_t;
    local result:2 = (word & mask) >> TOK_k4;
	Wnbf_t = result;
}

:bfins TOK_k4 "#"wid5, Wnbf_t, Wsb_t is
	OP_23_16=0x0A & OP_15_12=0x0 & Wnbf_t & TOK_k4b & TOK_k4;
	OP_23_16=0x0 & OP_15_8=0x0 & OP_7=0x0 & Wsb_t
[wid5 = TOK_k4b - TOK_k4 + 1;]
{
    local mask:2 = (0xff >> (16-(wid5 + 1))) << TOK_k4;
    local result:2 = (Wnbf_t & mask) >> TOK_k4;
	Wsb_t = result;
}

:bfins TOK_k4 "#"wid5, Wnbf_t, n15_t is
	OP_23_16=0x0A & OP_15_12=0x2 & Wnbf_t & TOK_k4b & TOK_k4;
	OP_23_16=0x0 & OP_0=0x0 & n15_t
[wid5 = TOK_k4b - TOK_k4 + 1;]
{
    local mask:2 = (0xff >> (16-(wid5 + 1))) << TOK_k4;
    local result:2 = (Wnbf_t & mask) >> TOK_k4;
	*:2 n15_t = result;
}


@endif


@if defined(dsPIC24F) || defined(dsPIC33E) || defined(dsPIC33C)
define pcodeop bootswap;
:bootswp is OP_23_0=0xFE2000 {
  bootswap();
}
@endif


:bra n16_t is OP_23_20=0x3 & OP_19_16=0x7 & n16_t {

  goto n16_t;
} 


@if defined(PIC24F) || defined(PIC24H) || defined(dsPIC30F) || defined(dsPIC33F) 
:bra Wns_t is  OP_23_20=0x0 & OP_19_16=0x1 & OP_15_12=0x6 & OP_11_8=0x0 & OP_7_4=0x0 & Wns_t & WordInstNext {

  #Note: identical operation as below, unique targets
  dest:3 = WordInstNext + 2 * sext(Wns_t);
  goto [dest];
} 
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:bra Wns_t is OP_23_20=0x0 & OP_19_16=0x1 & OP_15_12=0x0 & OP_11_8=0x6 & OP_7_4=0x0 & Wns_t  {

  #Note: identical operation as above, unique targets
  # inst_next is byte oriented here, and word oriented inside of [ ];
  dest:3 = (inst_next/2) + 2 * sext(Wns_t);
  goto [dest];
} 
@endif


cond1: "c" is  TOK_CCCC=0x1 { tmpBool:1 = SRL_C; export tmpBool; }
cond1: "ge" is  TOK_CCCC=0xD { tmpBool:1 = ((SRL_N && SRL_OV) || (!SRL_N && !SRL_OV)); export tmpBool; }
#Note: same as branch C, not supported in disassembly
# cond1: "geu" is  TOK_CCCC=0x1 { tmpBool:1 = SRL_C ); export tmpBool; }
cond1: "gt" is  TOK_CCCC=0xC
                { tmpBool:1 = ((!SRL_Z && SRL_N && SRL_OV) || (!SRL_Z && !SRL_N && !SRL_OV)); export tmpBool; }
cond1: "gtu" is  TOK_CCCC=0xE { tmpBool:1 = SRL_C && !SRL_Z; export tmpBool; }
cond1: "le" is  TOK_CCCC=0x4
                { tmpBool:1 = (SRL_Z || (SRL_N != SRL_OV)); export tmpBool; }
cond1: "leu" is  TOK_CCCC=0x6 { tmpBool:1 = (!SRL_C || SRL_Z); export tmpBool; }
cond1: "lt" is  TOK_CCCC=0x5 { tmpBool:1 = ((SRL_N && !SRL_OV) || (!SRL_N && SRL_OV)); export tmpBool; }
cond1: "n" is  TOK_CCCC=0x3 { tmpBool:1 = (SRL_N); export tmpBool; }
cond1: "nc" is  TOK_CCCC=0x9 { tmpBool:1 = (!SRL_C); export tmpBool; }
cond1: "nn" is  TOK_CCCC=0xB { tmpBool:1 = (!SRL_N); export tmpBool; }
cond1: "nov" is  TOK_CCCC=0x8 { tmpBool:1 = (!SRL_OV); export tmpBool; }
cond1: "nz" is  TOK_CCCC=0xA { tmpBool:1 = (!SRL_Z); export tmpBool; }
cond2: "oa" is  TOK_CCCC=0xC { tmpBool:1 = (SRH_OA); export tmpBool; }
cond2: "ob" is  TOK_CCCC=0xD { tmpBool:1 = (SRH_OB); export tmpBool; }
cond1: "ov" is  TOK_CCCC=0x0 { tmpBool:1 = (SRL_OV); export tmpBool; }
cond2: "sa" is  TOK_CCCC=0xE { tmpBool:1 = (SRH_SA); export tmpBool; }
cond2: "sb" is  TOK_CCCC=0xF { tmpBool:1 = (SRH_SB); export tmpBool; }
cond1: "z" is  TOK_CCCC=0x2 { tmpBool:1 = (SRL_Z); export tmpBool; }



##
##
##
## conditional branch for the 16-bit status branches above
##
##
##
:bra cond1,n16_t is OP_23_20=0x3 & cond1 & n16_t {

  if ( cond1 ) goto n16_t;
} 


##
##
##
## conditional branch for the 40-bit status branches above
##
##
##
:bra cond2,n16_t is OP_23_20=0x0 & cond2 & n16_t {

  if ( cond2 ) goto n16_t;
} 


:bset.w  f12_t,bit4_t is OP_23_20=0xA & OP_19_16=0x8 & bit4byte_t & bit4_t & f12_t {
 
  local mask:2 = 1 << bit4_t;
  f12_t = f12_t | mask;
} 


:bset.w  Wsb_t,Bbit4_t is
  OP_23_20=0xA & OP_19_16=0x0 & Bbit4_t & OP_11=0x0 & TOK_Bb=0 & OP_9_8=0x0 & OP_7=0x0 & $(WSconstraint) & Wsb_t {

  local mask:2 = 1 << Bbit4_t;
  Wsb_t = Wsb_t | mask;
} 


:bset.b  Wsbbyte_t,Bbit4_t is
  OP_23_20=0xA & OP_19_16=0x0 & Bbit4_t & OP_11=0x0 & TOK_Bb=1 & OP_9_8=0x0 & OP_7=0x0 & $(WSconstraint) & Wsbbyte_t {

  local mask:1 = 1 << Bbit4_t;
  Wsbbyte_t = Wsbbyte_t | mask;
} 


:bsw.c  Ws_t,Wbd_t is OP_23_20=0xA & OP_19_16=0xD & TOK_Z=0 & Wbd_t & OP_10_8=0x0 & OP_7=0x0 & $(WSconstraint) & Ws_t {

  # clear the bit and or flag in; write the bit
  local bit = Wbd_t & 0xF;
  Ws_t = ( Ws_t & ~(1 << bit) ) | (zext(SRL_C) << bit);
} 


:bsw.z  Ws_t,Wbd_t is OP_23_20=0xA & OP_19_16=0xD & TOK_Z=1 & Wbd_t & OP_10_8=0x0 & OP_7=0x0 & $(WSconstraint) & Ws_t {

  # clear the bit and or flag in; write the bit
  local bit = Wbd_t & 0xF;
  Ws_t = ( Ws_t & ~(1 << bit) ) | (zext(SRL_Z) << bit);
} 


:btg^bit4byte_t  f12_t,bit4_t is OP_23_20=0xA & OP_19_16=0xA & bit4byte_t & bit4_t & f12_t {

  local mask:2 = 1 << bit4_t;
  f12_t = f12_t ^ mask;
} 


# DSRPAG ????? 
:btg.w  Wsb_t,Bbit4_t is
        OP_23_20=0xA & OP_19_16=0x2 & Bbit4_t & OP_11=0x0 & TOK_Bb=0 & OP_9_8=0x0 & OP_7=0x0 & $(WSconstraint) & Wsb_t {

  local mask:2 = 1 << Bbit4_t;
  Wsb_t = Wsb_t ^ mask;
} 


:btg.b  Wsbbyte_t,Bbit4_t is
        OP_23_20=0xA & OP_19_16=0x2 & Bbit4_t & OP_11=0x0 & TOK_Bb=1 & OP_9_8=0x0 & OP_7=0x0 & $(WSconstraint) & Wsbbyte_t {

  local mask:1 = 1 << Bbit4_t;
  Wsbbyte_t = Wsbbyte_t ^ mask;
} 


:btsc^bit4byte_t  f12_t,bit4_t is OP_23_20=0xA & OP_19_16=0xF & bit4byte_t & bit4_t & f12_t
  [ skipInstr = 1; globalset(inst_next,skipInstr); ] {

  local mask:2 = 1 << bit4_t;
  SkipNextFlag = ( ( f12_t & mask ) == 0 );
} 


:btsc.w  Wsb_t,Bbit4_t is OP_23_16=0xa7 & OP_11_7=0x0 & Bbit4_t & $(WSconstraint) & Wsb_t
  [ skipInstr = 1; globalset(inst_next,skipInstr); ] {

  local mask:2 = 1 << Bbit4_t;
  SkipNextFlag = ( ( Wsb_t & mask ) == 0 );
} 


:btss^bit4byte_t  f12_t,bit4_t is OP_23_20=0xA & OP_19_16=0xE & bit4byte_t & bit4_t & f12_t
  [ skipInstr = 1; globalset(inst_next,skipInstr); ] {

  local mask:2 = 1 << bit4_t;
  SkipNextFlag = ( ( f12_t & mask ) != 0 );
} 


:btss.w  Wsb_t,Bbit4_t is OP_23_16=0xa6 & OP_11_7=0x0 & Bbit4_t & $(WSconstraint) & Wsb_t
  [ skipInstr = 1; globalset(inst_next,skipInstr); ] {

  local mask:2 = 1 << Bbit4_t;
  SkipNextFlag = ( ( Wsb_t & mask ) != 0 );
} 


:btst.w  f12_t,bit4_t is OP_23_20=0xA & OP_19_16=0xB & bit4byte_t & bit4_t & f12_t {

  local mask:2 = 1 << bit4_t;
  SRL_Z = ( ( f12_t & mask ) == 0 );
} 


# 						1010 0011 1111 0000 0000 0001
:btst.c  Wsb_t,Bbit4_t is 
	
    OP_23_16=0xa3 & OP_10_7=0x0 &
	Bbit4_t & TOK_Zb=0 & OP_10_8=0x0 & $(WSconstraint) & Wsb_t {

  local mask:2 = 1 << Bbit4_t;
  
  # set C to value of bit
  SRL_C = ( Wsb_t & mask ) != 0;
} 


:btst.z  Wsb_t,Bbit4_t is 
    
    OP_23_20=0xA & OP_19_16=0x3 & Bbit4_t & TOK_Zb=1 & OP_10_8=0x0 & OP_7=0x0 & $(WSconstraint) & Wsb_t {

  local mask:2 = 1 << Bbit4_t;

  # set Z to value of bit complemented
  SRL_Z = ( Wsb_t & mask ) == 0;
} 


:btst.c  Ws_t,Wbd_t is OP_23_20=0xA & OP_19_16=0x5 & TOK_Z=0 & Wbd_t & OP_10_8=0x0 & OP_7=0x0 & $(WSconstraint) & Ws_t {

  # set C to value of bit
  SRL_C = ( Ws_t & (1 << (Wbd_t & 0xF)) ) != 0;
} 


:btst.z  Ws_t,Wbd_t is OP_23_20=0xA & OP_19_16=0x5 & TOK_Z=1 & Wbd_t & OP_10_8=0x0 & OP_7=0x0 & $(WSconstraint) & Ws_t {

  # set Z to value of bit complemented
  SRL_Z = ( Ws_t & (1 << (Wbd_t & 0xF)) ) == 0;
} 


:btsts^bit4byte_t  f12_t,bit4_t is OP_23_20=0xA & OP_19_16=0xC & bit4byte_t & bit4_t & f12_t {

  local mask:2 = 1 << bit4_t;
  
  # set Z to value of bit complemented
  SRL_Z = ( ( f12_t & mask ) == 0 );

  # set value of bit to 1
  f12_t = f12_t | mask;
} 


# DSRPAG ?????  
:btsts.c  Wsb_t,Bbit4_t is OP_23_20=0xA & OP_19_16=0x4 & Bbit4_t & TOK_Zb=0 & OP_10_8=0x0 & OP_7=0x0 & $(WSconstraint) & Wsb_t {

  local mask:2 = 1 << Bbit4_t;
  local wsSrc = Wsb_t;
  
  # set C to value of bit
  SRL_C = ( wsSrc & mask ) != 0;

  # set value of bit to 1
  Wsb_t = wsSrc | mask;
} 


:btsts.z  Wsb_t,Bbit4_t is OP_23_20=0xA & OP_19_16=0x4 & Bbit4_t & TOK_Zb=1 & OP_10_8=0x0 & OP_7=0x0 & $(WSconstraint) & Wsb_t {

  local mask:2 = 1 << Bbit4_t;
  local wsSrc = Wsb_t;
  
  # set Z to value of bit complemented
  SRL_Z = ( wsSrc & mask ) == 0;

  # set value of bit to 1
  Wsb_t = wsSrc | mask;
} 


@if defined(PIC24F) || defined(PIC24H) || defined(dsPIC30F) || defined(dsPIC33F)
:call  dest24_t is ( OP_23_20=0x0 & OP_19_16=0x2 & OP_0=0x0 & WordInstNext4;
                     OP_23_20=0x0 & OP_19_16=0x0 & OP_15_12=0x0 & OP_11_8=0x0 & OP_7=0x0 ) & dest24_t  {

  *[ram]:4 W15  = WordInstNext4;
  W15           = W15 + 4;

  call dest24_t;
} 
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:call  dest24_t is ( OP_23_20=0x0 & OP_19_16=0x2 & OP_0=0x0;
                     OP_23_20=0x0 & OP_19_16=0x0 & OP_15_12=0x0 & OP_11_8=0x0 & OP_7=0x0 ) & dest24_t {

  *[ram]:4 W15  = (inst_next / 2) | zext(CORCON_SFA);
  W15           = W15 + 4;

  call dest24_t;
} 
@endif


@if defined(PIC24F) || defined(PIC24H) || defined(dsPIC30F) || defined(dsPIC33F) 
:call  WnDest_t is OP_23_20=0x0 & OP_19_16=0x1 & OP_15_12=0x0 & OP_11_8=0x0 & OP_7_4=0x0 & WnDest_t & WordInstNext4 {

  *[ram]:4 W15  = WordInstNext4;
  W15           = W15 + 4;

  call [WnDest_t];
} 
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:call  WnDest_t is OP_23_20=0x0 & OP_19_16=0x1 & OP_15_12=0x0 & OP_11_8=0x0 & OP_7_4=0x0 & WnDest_t & WordInstNext4 {

  *[ram]:4 W15  = WordInstNext4 | zext(CORCON_SFA);
  W15           = W15 + 4;

  call [WnDest_t];
} 
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:call.l  WnWn1_t is OP_23_20=0x0 & OP_19_16=0x1 & OP_15=0x1 & WnWn1_t & OP_10_8=0x0 & OP_7_4=0x0 & WordInstNext4 {

  *[ram]:4 W15  = WordInstNext4 | zext(CORCON_SFA);
  W15           = W15 + 4;

  call [WnWn1_t];
} 
@endif


:clr.w   f13b_t is OP_23_20=0xE & OP_19_16=0xF & OP_15=0 & f13b_t {

  f13b_t = 0;
} 


:clr.w   WREGb_t is OP_23_20=0xE & OP_19_16=0xF & OP_15=0 & WREGb_t {

  WREGb_t = 0;
} 


:clr.b f13bbyte_t is OP_23_20=0xE & OP_19_16=0xF & OP_15=0 & f13bbyte_t {

  f13bbyte_t = 0;
}


:clr.b WREGbbyte_t is OP_23_20=0xE & OP_19_16=0xF & OP_15=0 & WREGbbyte_t {

  WREGbbyte_t = 0;
}


:clr.w   Wd_t is OP_23_20=0xE & OP_19_16=0xB & OP_15=0x0 & TOK_B=0 & $(WDconstraint) & Wd_t & OP_6_4=0x0 & OP_3_0=0x0 {

  Wd_t = 0;
} 


:clr.b  Wdbyte_t is OP_23_20=0xE & OP_19_16=0xB & OP_15=0x0 & TOK_B=1 & $(WDconstraint) & Wdbyte_t & OP_6_4=0x0 & OP_3_0=0x0 {

  Wdbyte_t = 0;
} 

@if defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) || defined(dsPIC33C)
#
# Note: The following constructors have three optional parameters, Wx, Wy and AWB.  To implement them
# without if-then-else constructs, the permutations were made.  The TOK tokens correspond, in order,
# with the elements that are removed (commented out) from the constructor when the "no prefetch"
# or "no write back" cases occur.  Corresponding sub-constructors were also removed from the display
# section because an unused destination would otherwise be displayed (i.e. "clr ACCAW4W4" -> "clr ACCA").
#

##
##
## ACCA series
##
##

:clr ACCA_t is 
     OP_23_20=0xC & OP_19_16=0x3 & ACCA_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 & TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # 0 -> ACCA
  ACCA 		= 0;
  SRH_OA 	= 0;
  SRH_SA 	= 0;

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
#  AWB_t = ACCBH;
} 


:clr ACCA_t^AWB_t is 
     OP_23_20=0xC & OP_19_16=0x3 & ACCA_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # 0 -> ACCA
  ACCA 		= 0;
  SRH_OA 	= 0;
  SRH_SA 	= 0;

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
  AWB_t = ACCBH;
} 


:clr ACCA_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19_16=0x3 & ACCA_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 &                    TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # 0 -> ACCA
  ACCA 		= 0;
  SRH_OA 	= 0;
  SRH_SA 	= 0;

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
#  AWB_t = ACCBH;
} 


:clr ACCA_t^Wy_t^Wyd_t^AWB_t is 
     OP_23_20=0xC & OP_19_16=0x3 & ACCA_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # 0 -> ACCA
  ACCA 		= 0;
  SRH_OA 	= 0;
  SRH_SA 	= 0;

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
  AWB_t = ACCBH;
} 


:clr ACCA_t^Wx_t^Wxd_t is 
     OP_23_20=0xC & OP_19_16=0x3 & ACCA_t & OP_14=0x0 &
                        TOK_5_2_jjjj=0x4 & TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # 0 -> ACCA
  ACCA 		= 0;
  SRH_OA 	= 0;
  SRH_SA 	= 0;

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
#  AWB_t = ACCBH;
} 


:clr ACCA_t^Wx_t^Wxd_t^AWB_t is 
     OP_23_20=0xC & OP_19_16=0x3 & ACCA_t & OP_14=0x0 &
                        TOK_5_2_jjjj=0x4 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # 0 -> ACCA
  ACCA 		= 0;
  SRH_OA 	= 0;
  SRH_SA 	= 0;

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
  AWB_t = ACCBH;
} 


:clr ACCA_t^Wx_t^Wxd_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19_16=0x3 & ACCA_t & OP_14=0x0 &
                                           TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # 0 -> ACCA
  ACCA 		= 0;
  SRH_OA 	= 0;
  SRH_SA 	= 0;

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
#  AWB_t = ACCBH;
} 


:clr ACCA_t^Wx_t^Wxd_t^Wy_t^Wyd_t^AWB_t is 
     OP_23_20=0xC & OP_19_16=0x3 & ACCA_t & OP_14=0x0 &
      
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # 0 -> ACCA
  ACCA 		= 0;
  SRH_OA 	= 0;
  SRH_SA 	= 0;

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
  AWB_t = ACCBH;
} 

##
##
## ACCB series
##
##

:clr ACCB_t is 
     OP_23_20=0xC & OP_19_16=0x3 & ACCB_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 & TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  ACCB 		= 0;
  SRH_OB 	= 0;
  SRH_SB 	= 0;

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
#  AWB_t = ACCAH;
}

 
:clr ACCB_t^AWB_t is 
     OP_23_20=0xC & OP_19_16=0x3 & ACCB_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  ACCB 		= 0;
  SRH_OB 	= 0;
  SRH_SB 	= 0;

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
  AWB_t = ACCAH;
}

 
:clr ACCB_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19_16=0x3 & ACCB_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 &                    TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  ACCB 		= 0;
  SRH_OB 	= 0;
  SRH_SB 	= 0;

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
#  AWB_t = ACCAH;
}

 
:clr ACCB_t^Wy_t^Wyd_t^AWB_t is 
     OP_23_20=0xC & OP_19_16=0x3 & ACCB_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 &
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  ACCB 		= 0;
  SRH_OB 	= 0;
  SRH_SB 	= 0;

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
  AWB_t = ACCAH;
}

 
:clr ACCB_t^Wy_t^Wyd_t^AWB_t is 
     OP_23_20=0xC & OP_19_16=0x3 & ACCB_t & OP_14=0x0 &
                        TOK_5_2_jjjj=0x4 & TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  ACCB 		= 0;
  SRH_OB 	= 0;
  SRH_SB 	= 0;

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
#  AWB_t = ACCAH;
}

 
:clr ACCB_t^Wx_t^Wxd_t^AWB_t is 
     OP_23_20=0xC & OP_19_16=0x3 & ACCB_t & OP_14=0x0 &
                        TOK_5_2_jjjj=0x4 &
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  ACCB 		= 0;
  SRH_OB 	= 0;
  SRH_SB 	= 0;

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
  AWB_t = ACCAH;
}

 
:clr ACCB_t^Wx_t^Wxd_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19_16=0x3 & ACCB_t & OP_14=0x0 &
                                           TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  ACCB 		= 0;
  SRH_OB 	= 0;
  SRH_SB 	= 0;

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
#  AWB_t = ACCAH;
}

 
:clr ACCB_t^Wx_t^Wxd_t^Wy_t^Wyd_t^AWB_t is 
     OP_23_20=0xC & OP_19_16=0x3 & ACCB_t & OP_14=0x0 &

     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  ACCB 		= 0;
  SRH_OB 	= 0;
  SRH_SB 	= 0;

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
  AWB_t = ACCAH;
}
@endif


:clrwdt is OP_23_20=0xF & OP_19_16=0xE & OP_15_12=0x6 & OP_11_8=0x0 & OP_7_4=0x0 & OP_3_0=0x0 {

  WDTcount      = 0;    # ????? formal name not documented
  WDTprescalarA = 0;    # ????? formal name not documented
  WDTprescalarB = 0;    # ????? formal name not documented
}


:com.w   f13_t^WREG_t is OP_23_20=0xE & OP_19_16=0xE & OP_15=1 & WREG_t & f13_t {

  WREG_t =       ~f13_t;

  testSRL_N     ( WREG_t );
  testSRL_Z     ( WREG_t );
} 

:com.b f13byte_t^WREGbyte_t is OP_23_20=0xE & OP_19_16=0xE & OP_15=1 & WREGbyte_t & f13byte_t {

  WREGbyte_t =   ~f13byte_t;

  testSRL_N     ( WREGbyte_t );
  testSRL_Z     ( WREGbyte_t );
}


:com.w   Ws_t,Wd_t is OP_23_20=0xE & OP_19_16=0xA & OP_15=0x1 & TOK_B=0 & $(WDconstraint) & Wd_t & $(WSconstraint) & Ws_t {

  local result  =   ~Ws_t;
  build Wd_t;
  Wd_t = result;

  testSRL_N     ( result );
  testSRL_Z     ( result );
} 


:com.b  Wsbyte_t,Wdbyte_t is OP_23_20=0xE & OP_19_16=0xA & OP_15=0x1 & TOK_B=1 & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & Wsbyte_t {

  local result  =   ~Wsbyte_t;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
} 


:cp.w   f13_t is OP_23_20=0xE & OP_19_16=0x3 & OP_15=0 & OP_13=0 & f13_t {

  local src = f13_t;
  subflags( src,  W0 );

  local tmp:2 = src - W0;

  testSRL_N     ( tmp );
  testSRL_Z     ( tmp );
  testSRH_DCword( tmp );
} 


:cp.b f13byte_t is OP_23_20=0xE & OP_19_16=0x3 & OP_15=0 & OP_13=0 & f13byte_t {

  local src = f13byte_t;
  subflags( src,  W0byte );

  local tmp:1 = src - W0byte;

  testSRL_N     ( tmp );
  testSRL_Z     ( tmp );
  testSRH_DCbyte( tmp );
}


@if defined(PIC24F) || defined(PIC24H) || defined(dsPIC30F) || defined(dsPIC33F) 
:cp.w   Wbb_t,k5_B10_t is OP_23_20=0xE & OP_19_16=0x1 & OP_15=0x0 & OP_9_8=0x0 & OP_7_5=0x3 & Wbb_t & k5_B10_t {

  subflags( Wbb_t,  k5_B10_t );

  tmp:2 =        Wbb_t - k5_B10_t;

  testSRL_N     ( tmp );
  testSRL_Z     ( tmp );
  testSRH_DCword( tmp );
} 


:cp.b  Wbbbyte_t,k5byte_B10_t is
       OP_23_20=0xE & OP_19_16=0x1 & OP_15=0x0 & OP_9_8=0x0 & OP_7_5=0x3 & Wbbbyte_t & k5byte_B10_t {

  subflags( Wbbbyte_t,  k5byte_B10_t );

  tmp:1 =        Wbbbyte_t - k5byte_B10_t;

  testSRL_N     ( tmp );
  testSRL_Z     ( tmp );
  testSRH_DCbyte( tmp );
} 
@endif

@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)

:cp.w   Wbb_t,k8_t is OP_23_20=0xE & OP_19_16=0x1 & OP_15=0x0 & TOK_Bb=0 & OP_6_5=0x3 & Wbb_t & k8_t {

  subflags( Wbb_t,  k8_t );

  tmp:2 =        Wbb_t - k8_t;

  testSRL_N     ( tmp );
  testSRL_Z     ( tmp );
  testSRH_DCword( tmp );
} 


:cp.b  Wbbbyte_t,k8byte_t is OP_23_20=0xE & OP_19_16=0x1 & OP_15=0x0 & TOK_Bb=1 & OP_6_5=0x3 & Wbbbyte_t & k8byte_t {

  subflags( Wbbbyte_t,  k8byte_t );

  tmp:1 =        Wbbbyte_t - k8byte_t;

  testSRL_N     ( tmp );
  testSRL_Z     ( tmp );
  testSRH_DCbyte( tmp );
} 
@endif


:cp.w   Wbb_t,Wsb_t is OP_23_20=0xE & OP_19_16=0x1 & OP_15=0x0 & TOK_Bb=0 & OP_9_8=0x0 & OP_7=0x0 & Wbb_t & $(WSconstraint) & Wsb_t {

  local src = Wsb_t;
  subflags( Wbb_t,  src );

  tmp:2 =        Wbb_t - src;

  testSRL_N     ( tmp );
  testSRL_Z     ( tmp );
  testSRH_DCword( tmp );
} 


:cp.b  Wbbbyte_t,Wsbbyte_t is
       OP_23_20=0xE & OP_19_16=0x1 & OP_15=0x0 & TOK_Bb=1 & OP_9_8=0x0 & OP_7=0x0 & Wbbbyte_t & $(WSconstraint) & Wsbbyte_t {

  local src = Wsbbyte_t;
  subflags( Wbbbyte_t,  src );

  tmp:1 =        Wbbbyte_t - src;

  testSRL_N     ( tmp );
  testSRL_Z     ( tmp );
  testSRH_DCbyte( tmp );
} 


:cp0.w   f13_t is OP_23_20=0xE & OP_19_16=0x2 & OP_15=0 & OP_13=0 & f13_t {

  local src = f13_t;
  local zero:2 = 0;
  subflags( src, zero );

  testSRL_N     ( src );
  testSRL_Z     ( src );
  testSRH_DCword( src );
} 


:cp0.b f13byte_t is OP_23_20=0xE & OP_19_16=0x2 & OP_15=0 & OP_13=0 & f13byte_t {

  local src = f13byte_t;
  local zero:1 = 0;
  subflags( src, zero );

  testSRL_N     ( src );
  testSRL_Z     ( src );
  testSRH_DCbyte( src );
}


:cp0.w   Wsb_t is OP_23_20=0xE & OP_19_16=0x0 & OP_15_12=0x0 & OP_11=0x0 & TOK_Bb=0 & OP_9_8=0x0 & OP_7=0x0 & $(WSconstraint) & Wsb_t {

  local src = Wsb_t;
  local zero:2 = 0;
  subflags( src, zero );

  testSRL_N     ( src );
  testSRL_Z     ( src );
  testSRH_DCword( src );
} 


:cp0.b  Wsbbyte_t is OP_23_20=0xE & OP_19_16=0x0 & OP_15_12=0x0 & OP_11=0x0 & TOK_Bb=1 & OP_9_8=0x0 & OP_7=0x0 & $(WSconstraint) & Wsbbyte_t {

  local src = Wsbbyte_t;
  local zero:1 = 0;
  subflags( src, zero );

  testSRL_N     ( src );
  testSRL_Z     ( src );
  testSRH_DCbyte( src );
} 


:cpb.w   f13_t is OP_23_20=0xE & OP_19_16=0x3 & OP_15=1 & OP_13=0 & f13_t {

  local notCarry:2 = zext(!SRL_C);
  local src = f13_t;
  subflagsWithCarry( src,  W0, notCarry );

  tmp:2 =         src - W0 - notCarry;

  testSRL_N      ( tmp );
  testSRL_Zsticky( tmp );
  testSRH_DCword ( tmp );
} 


:cpb.b f13byte_t is OP_23_20=0xE & OP_19_16=0x3 & OP_15=1 & OP_13=0 & f13byte_t {

  local notCarry = !SRL_C;
  local src = f13byte_t;
  subflagsWithCarry( src,  W0byte,  notCarry );

  tmp:1 =             src - W0byte - notCarry;

  testSRL_N      ( tmp );
  testSRL_Zsticky( tmp );
  testSRH_DCbyte ( tmp );
}


@if defined(PIC24F) || defined(PIC24H) || defined(dsPIC30F) || defined(dsPIC33F) 
:cpb.w  Wb_t,k5_t is OP_23_20=0xE & OP_19_16=0x1 & OP_15=0x1 & OP_9_8=0x0 & OP_7_5=0x3 & Wb_t & k5_t {

  local notCarry:2 = zext(!SRL_C);
  subflagsWithCarry( Wb_t,  k5_t, notCarry );

  tmp:2 =         Wb_t - k5_t - notCarry;

  testSRL_N      ( tmp );
  testSRL_Zsticky( tmp );
  testSRH_DCword ( tmp );
} 


:cpb.b  Wbbyte_t,k5byte_t is
        OP_23_20=0xE & OP_19_16=0x1 & OP_15=0x1 & OP_9_8=0x0 & OP_7_5=0x3 & Wbbyte_t & k5byte_t {

  local notCarry = !SRL_C;
  subflagsWithCarry( Wbbyte_t,  k5byte_t,  notCarry );

  tmp:1 =             Wbbyte_t - k5byte_t - notCarry;

  testSRL_N      ( tmp );
  testSRL_Zsticky( tmp );
  testSRH_DCbyte ( tmp );
} 
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:cpb.w   Wbb_t,k8_t is OP_23_20=0xE & OP_19_16=0x1 & OP_15=0x1 & TOK_Bb=0 & OP_6_5=0x3 & Wbb_t & k8_t {

  local notCarry:2 = zext(!SRL_C);
  subflagsWithCarry( Wbb_t, k8_t, notCarry );

  tmp:2 =         Wbb_t - k8_t - notCarry;

  testSRL_N      ( tmp );
  testSRL_Zsticky( tmp );
  testSRH_DCword ( tmp );
} 


:cpb.b  Wbbbyte_t,k8byte_t is OP_23_20=0xE & OP_19_16=0x1 & OP_15=0x1 & TOK_Bb=1 & OP_6_5=0x3 & Wbbbyte_t & k8byte_t {

  local notCarry = !SRL_C;
  subflagsWithCarry( Wbbbyte_t,  k8byte_t,  notCarry );

  tmp:1 =             Wbbbyte_t - k8byte_t - notCarry;

  testSRL_N      ( tmp );
  testSRL_Zsticky( tmp );
  testSRH_DCbyte ( tmp );
} 
@endif


:cpb.w   Wbb_t,Wsb_t is OP_23_20=0xE & OP_19_16=0x1 & OP_15=0x1 & TOK_Bb=0 & OP_9_8=0x0 & OP_7=0x0 & Wbb_t & $(WSconstraint) & Wsb_t {

  local notCarry:2 = zext(!SRL_C);
  local src = Wsb_t;
  subflagsWithCarry( Wbb_t,  src, notCarry );
 
  tmp:2 =         Wbb_t - src - notCarry;

  testSRL_N      ( tmp );
  testSRL_Zsticky( tmp );
  testSRH_DCword ( tmp );
} 


:cpb.b  Wbbbyte_t,Wsbbyte_t is
        OP_23_20=0xE & OP_19_16=0x1 & OP_15=0x1 & TOK_Bb=1 & OP_9_8=0x0 & OP_7=0x0 & Wbbbyte_t & $(WSconstraint) & Wsbbyte_t {

  local notCarry = !SRL_C;
  local src = Wsbbyte_t;
  subflagsWithCarry( Wbbbyte_t,  src,  notCarry );

  tmp:1 =             Wbbbyte_t - src - notCarry;

  testSRL_N      ( tmp );
  testSRL_Zsticky( tmp );
  testSRH_DCbyte ( tmp );
} 


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:cpbeq.w   Wbb_t,Wnb_t,n6_t is OP_23_20=0xE & OP_19_16=0x7 & OP_15=0x1 & TOK_Bb=0 & Wbb_t & n6_t & Wnb_t {

  if (Wbb_t == Wnb_t) goto n6_t; # ????? what about the flags, examples show them setting?
} 


:cpbeq.b  Wbbbyte_t,Wnbbyte_t,n6_t is
          OP_23_20=0xE & OP_19_16=0x7 & OP_15=0x1 & TOK_Bb=1 & Wbbbyte_t & n6_t & Wnbbyte_t {

  if (Wbbbyte_t == Wnbbyte_t) goto n6_t;
} 
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:cpbgt.w   Wbb_t,Wnb_t,n6_t is OP_23_20=0xE & OP_19_16=0x6 & OP_15=0x0 & TOK_Bb=0 & Wbb_t & n6_t & Wnb_t {

  if (Wbb_t s> Wnb_t) goto n6_t; # ????? what about the flags, examples show them setting?
} 


:cpbgt.b  Wbbbyte_t,Wnbbyte_t,n6_t is
          OP_23_20=0xE & OP_19_16=0x6 & OP_15=0x0 & TOK_Bb=1 & Wbbbyte_t & n6_t & Wnbbyte_t {

  if (Wbbbyte_t s> Wnbbyte_t) goto n6_t;
} 
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:cpblt.w   Wbb_t,Wnb_t,n6_t is OP_23_20=0xE & OP_19_16=0x6 & OP_15=0x1 & TOK_Bb=0 & Wbb_t & n6_t & Wnb_t {

  if (Wbb_t s< Wnb_t) goto n6_t; # ????? what about the flags, examples show them setting?
} 


:cpblt.b  Wbbbyte_t,Wnbbyte_t,n6_t is
          OP_23_20=0xE & OP_19_16=0x6 & OP_15=0x1 & TOK_Bb=1 & Wbbbyte_t & n6_t & Wnbbyte_t {

  if (Wbbbyte_t s< Wnbbyte_t) goto n6_t;
} 
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:cpbne.w   Wbb_t,Wnb_t,n6_t is OP_23_20=0xE & OP_19_16=0x7 & OP_15=0x0 & TOK_Bb=0 & Wbb_t & n6_t & Wnb_t {

  if (Wbb_t != Wnb_t) goto n6_t; # ????? what about the flags, examples show them setting?
} 


:cpbne.b  Wbbbyte_t,Wnbbyte_t,n6_t is OP_23_20=0xE & OP_19_16=0x7 & OP_15=0x0 & TOK_Bb=1 & Wbbbyte_t & n6_t & Wnbbyte_t {

  if (Wbbbyte_t != Wnbbyte_t) goto n6_t;
} 
@endif


@if defined(PIC24F) || defined(PIC24H) || defined(dsPIC30F) || defined(dsPIC33F) 
:cpseq.w   Wbb_t,Wnb_t is
         OP_23_20=0xE & OP_19_16=0x7 & OP_15=0x1 & TOK_Bb=0 & Wbb_t & OP_9_8=0x0 & OP_7_4=0x0 & Wnb_t
  [ skipInstr = 1; globalset(inst_next,skipInstr); ] {

  SkipNextFlag = (Wbb_t == Wnb_t); # ????? what about the flags, examples show them setting?
} 


:cpseq.b  Wbbbyte_t,Wnbbyte_t is
          OP_23_20=0xE & OP_19_16=0x7 & OP_15=0x1 & TOK_Bb=1 & Wbbbyte_t & OP_9_8=0x0 & OP_7_4=0x0 & Wnbbyte_t
  [ skipInstr = 1; globalset(inst_next,skipInstr); ] {

  SkipNextFlag = (Wbbbyte_t == Wnbbyte_t);
} 
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:cpseq.w   Wbb_t,Wnb_t is
         OP_23_20=0xE & OP_19_16=0x7 & OP_15=0x1 & TOK_Bb=0 & Wbb_t & OP_9_8=0x0 & OP_7_4=0x1 & Wnb_t
  [ skipInstr = 1; globalset(inst_next,skipInstr); ] {

  SkipNextFlag = (Wbb_t == Wnb_t); # ????? what about the flags, examples show them setting?
} 


:cpseq.b  Wbbbyte_t,Wnbbyte_t is
          OP_23_20=0xE & OP_19_16=0x7 & OP_15=0x1 & TOK_Bb=1 & Wbbbyte_t & OP_9_8=0x0 & OP_7_4=0x1 & Wnbbyte_t
  [ skipInstr = 1; globalset(inst_next,skipInstr); ] {

  SkipNextFlag = (Wbbbyte_t == Wnbbyte_t);
} 
@endif


@if defined(PIC24F) || defined(PIC24H) || defined(dsPIC30F) || defined(dsPIC33F) 
:cpsgt.w   Wbb_t,Wnb_t is
         OP_23_20=0xE & OP_19_16=0x6 & OP_15=0x0 & TOK_Bb=0 & Wbb_t & OP_9_8=0x0 & OP_7_4=0x0 & Wnb_t
  [ skipInstr = 1; globalset(inst_next,skipInstr); ] {

  SkipNextFlag = (Wbb_t s> Wnb_t); # ????? what about the flags, examples show them setting?
} 


:cpsgt.b  Wbbbyte_t,Wnbbyte_t is
          OP_23_20=0xE & OP_19_16=0x6 & OP_15=0x0 & TOK_Bb=1 & Wbbbyte_t & OP_9_8=0x0 & OP_7_4=0x0 & Wnbbyte_t
  [ skipInstr = 1; globalset(inst_next,skipInstr); ] {

  SkipNextFlag = (Wbbbyte_t s> Wnbbyte_t);
} 
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:cpsgt.w   Wbb_t,Wnb_t is
         OP_23_20=0xE & OP_19_16=0x6 & OP_15=0x0 & TOK_Bb=0 & Wbb_t & OP_9_8=0x0 & OP_7_4=0x1 & Wnb_t
  [ skipInstr = 1; globalset(inst_next,skipInstr); ] {

  SkipNextFlag = (Wbb_t s> Wnb_t); # ????? what about the flags, examples show them setting?
} 


:cpsgt.b  Wbbbyte_t,Wnbbyte_t is
          OP_23_20=0xE & OP_19_16=0x6 & OP_15=0x0 & TOK_Bb=1 & Wbbbyte_t & OP_9_8=0x0 & OP_7_4=0x1 & Wnbbyte_t
  [ skipInstr = 1; globalset(inst_next,skipInstr); ] {

  SkipNextFlag = (Wbbbyte_t s> Wnbbyte_t);
} 
@endif


@if defined(PIC24F) || defined(PIC24H) || defined(dsPIC30F) || defined(dsPIC33F) 
:cpslt.w   Wbb_t,Wnb_t is
         OP_23_20=0xE & OP_19_16=0x6 & OP_15=0x1 & TOK_Bb=0 & Wbb_t & OP_9_8=0x0 & OP_7_4=0x0 & Wnb_t
  [ skipInstr = 1; globalset(inst_next,skipInstr); ] {

  SkipNextFlag = (Wbb_t s< Wnb_t); # ????? what about the flags, examples show them setting?
} 


:cpslt.b  Wbbbyte_t,Wnbbyte_t is
          OP_23_20=0xE & OP_19_16=0x6 & OP_15=0x1 & TOK_Bb=1 & Wbbbyte_t & OP_9_8=0x0 & OP_7_4=0x0 & Wnbbyte_t
  [ skipInstr = 1; globalset(inst_next,skipInstr); ] {

  SkipNextFlag = (Wbbbyte_t s< Wnbbyte_t);
} 
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:cpslt.w   Wbb_t,Wnb_t is
         OP_23_20=0xE & OP_19_16=0x6 & OP_15=0x1 & TOK_Bb=0 & Wbb_t & OP_9_8=0x0 & OP_7_4=0x1 & Wnb_t
  [ skipInstr = 1; globalset(inst_next,skipInstr); ] {

  SkipNextFlag = (Wbb_t s< Wnb_t); # ????? what about the flags, examples show them setting?
} 


:cpslt.b  Wbbbyte_t,Wnbbyte_t is
          OP_23_20=0xE & OP_19_16=0x6 & OP_15=0x1 & TOK_Bb=1 & Wbbbyte_t & OP_9_8=0x0 & OP_7_4=0x1 & Wnbbyte_t
  [ skipInstr = 1; globalset(inst_next,skipInstr); ] {

  SkipNextFlag = (Wbbbyte_t s< Wnbbyte_t);
} 
@endif


@if defined(PIC24F) || defined(PIC24H) || defined(dsPIC30F) || defined(dsPIC33F) 
:cpsne.w   Wbb_t,Wnb_t is
         OP_23_20=0xE & OP_19_16=0x7 & OP_15=0x0 & TOK_Bb=0 & Wbb_t & OP_9_8=0x0 & OP_7_4=0x0 & Wnb_t
  [ skipInstr = 1; globalset(inst_next,skipInstr); ] {

  SkipNextFlag = (Wbb_t != Wnb_t); # ????? what about the flags, examples show them setting?
} 


:cpsne.b  Wbbbyte_t,Wnbbyte_t is
          OP_23_20=0xE & OP_19_16=0x7 & OP_15=0x0 & TOK_Bb=1 & Wbbbyte_t & OP_9_8=0x0 & OP_7_4=0x0 & Wnbbyte_t
  [ skipInstr = 1; globalset(inst_next,skipInstr); ] {

  SkipNextFlag = (Wbbbyte_t != Wnbbyte_t);
} 
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:cpsne.w   Wbb_t,Wnb_t is
         OP_23_20=0xE & OP_19_16=0x7 & OP_15=0x0 & TOK_Bb=0 & Wbb_t & OP_9_8=0x0 & OP_7_4=0x1 & Wnb_t
  [ skipInstr = 1; globalset(inst_next,skipInstr); ] {

  SkipNextFlag = (Wbb_t != Wnb_t); # ????? what about the flags, examples show them setting?
} 


:cpsne.b  Wbbbyte_t,Wnbbyte_t is
          OP_23_20=0xE & OP_19_16=0x7 & OP_15=0x0 & TOK_Bb=1 & Wbbbyte_t & OP_9_8=0x0 & OP_7_4=0x1 & Wnbbyte_t
  [ skipInstr = 1; globalset(inst_next,skipInstr); ] {

  SkipNextFlag = (Wbbbyte_t != Wnbbyte_t);
} 
@endif


@if defined(dsPIC33E) || defined(dsPIC33C)
define pcodeop contextswap;
:ctxtswp k3_t is OP_23_4=0xFE200 & OP_3=0x0 & k3_t {
  contextswap(k3_t);
}

:ctxtswp Wndb_t is OP_23_4=0xFEF00 & Wndb_t {
  contextswap(Wndb_t);
}
@endif

:daw.b Wnsbyte_t is OP_23_20=0xF & OP_19_16=0xD & OP_15_12=0x4 & OP_11_8=0x0 & OP_7_4=0x0 & Wnsbyte_t {

  if !( ( ( Wnsbyte_t & 0x0F ) > 0x09 ) || SRH_DC ) goto <else1>;
    Wnsbyte_t = Wnsbyte_t + 0x06;
  <else1>

  if !( ( ( Wnsbyte_t & 0xF0 ) > 0x90 ) || SRL_C ) goto <else2>;
    Wnsbyte_t = Wnsbyte_t + 0x60;
    SRL_C = 1;
  <else2>
} 


:dec.w   f13_t,^WREG_t  is OP_23_20=0xE & OP_19_16=0xD & OP_15=0 & WREG_t & f13_t {

  local src = f13_t;
  local one:2 = 1;
  subflags( src, one );

  WREG_t =       src - one;

  testSRL_N     ( WREG_t );
  testSRL_Z     ( WREG_t );
  testSRH_DCword( WREG_t );
} 


:dec.b f13byte_t^WREGbyte_t is OP_23_20=0xE & OP_19_16=0xD & OP_15=0 & WREGbyte_t & f13byte_t {

  local src = f13byte_t;
  local one:1 = 1;
  subflags( src, one );

  WREGbyte_t =   src - one;

  testSRL_N     ( WREGbyte_t );
  testSRL_Z     ( WREGbyte_t );
  testSRH_DCbyte( WREGbyte_t );
}


:dec.w   Ws_t,Wd_t is OP_23_20=0xE & OP_19_16=0x9 & OP_15=0x0 & TOK_B=0 & $(WDconstraint) & Wd_t & $(WSconstraint) & Ws_t {

  local src = Ws_t;
  local one:2 = 1;
  subflags( src, one );

  local result = src - one;
  build Wd_t;
  Wd_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCword( result );
} 


:dec.b  Wsbyte_t,Wdbyte_t is OP_23_20=0xE & OP_19_16=0x9 & OP_15=0x0 & TOK_B=1 & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & Wsbyte_t {

  local src = Wsbyte_t;
  local one:1 = 1;
  subflags( src, one );

  local result = src - one;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCbyte( result );
} 


:dec2.w   f13_t^WREG_t is OP_23_20=0xE & OP_19_16=0xD & OP_15=1 & WREG_t & f13_t {

  local src = f13_t;
  local two:2 = 2;
  subflags( src,  two );

  WREG_t =       src - two;

  testSRL_N     ( WREG_t );
  testSRL_Z     ( WREG_t );
  testSRH_DCword( WREG_t );
} 


:dec2.b f13byte_t^WREGbyte_t is OP_23_20=0xE & OP_19_16=0xD & OP_15=1 & WREGbyte_t & f13byte_t {

  local src = f13byte_t;
  local two:1 = 2;
  subflags( src, two );

  WREGbyte_t =   src - two;

  testSRL_N     ( WREGbyte_t );
  testSRL_Z     ( WREGbyte_t );
  testSRH_DCbyte( WREGbyte_t );
}


:dec2.w   Ws_t,Wd_t is OP_23_20=0xE & OP_19_16=0x9 & OP_15=0x1 & TOK_B=0 & $(WDconstraint) & Wd_t & $(WSconstraint) & Ws_t {

  local src = Ws_t;
  local two:2 = 2;
  subflags( src, two );

  local result = src - two;
  build Wd_t;
  Wd_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCword( result );
} 


:dec2.b  Wsbyte_t,Wdbyte_t is OP_23_20=0xE & OP_19_16=0x9 & OP_15=0x1 & TOK_B=1 & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & Wsbyte_t {

  local src = Wsbyte_t;
  local two:1 = 2;
  subflags( src, two );
 
  local result = src - two;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCbyte( result );
} 


:disi  k14_t is OP_23_20=0xF & OP_19_16=0xC & OP_15_14=0x0 & k14_t {

  DISICNT 	= k14_t;
  DISI 		= 1;
} 


:repeat" 0x11 div.sw"   TOK_10_7_Wreg,TOK_3_0_Wreg is
          OP_31_0=0x090011;
          OP_23_20=0xD & OP_19_16=0x8 & OP_15=0x0 & TOK_10_7_Wreg & TOK_W=0 & OP_5_4=0x0 & TOK_3_0_Wreg {

  # Note: this implementation is not iterative, like the actual op.
  # Rather, it will decompile accurately and emulate correctly using the Sleigh divide support.
  local div:2 = sext(TOK_10_7_Wreg) s/ sext(TOK_3_0_Wreg);
  local rem:2 = sext(TOK_10_7_Wreg) s% sext(TOK_3_0_Wreg);

  W0 = div:1;
  W1 = rem:1;
  
  testSRL_N     ( W1 );

  # overflow as defined in note 2
  SRL_OV = (TOK_10_7_Wreg == 0x8000) && (TOK_3_0_Wreg == 0xFFFF);

  testSRL_Z     ( W1 );

  # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis
  SRL_C  = 0;
} 

define pcodeop pic30_div;
define pcodeop pic30_rem;

:div.sw   TOK_10_7_Wreg,TOK_3_0_Wreg is
          OP_23_20=0xD & OP_19_16=0x8 & OP_15=0x0 & TOK_10_7_Wreg & TOK_W=0 & OP_5_4=0x0 & TOK_3_0_Wreg {
  local div:2 = pic30_div(TOK_10_7_Wreg,TOK_3_0_Wreg);
  local rem:2 = pic30_rem(TOK_10_7_Wreg,TOK_3_0_Wreg);

  W0 = div;
  W1 = rem;
  
  testSRL_N     ( W1 );
  # overflow as defined in note 2
  SRL_OV = (TOK_10_7_Wreg == 0x8000) && (TOK_3_0_Wreg == 0xFFFF);
  testSRL_Z     ( W1 );

  # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis
  SRL_C  = 0;
}

define pcodeop isDivideOverflow;

:repeat" 0x11 div.sd"  TOK_10_8_Dregn,TOK_3_0_Wreg is
         OP_31_0=0x090011;
         OP_23_20=0xD & OP_19_16=0x8 & OP_15=0x0 &
         TOK_10_8_Dreg & TOK_10_8_Dregn & OP_7=0 & TOK_W=1 & OP_5_4=0x0 & TOK_3_0_Wreg {

  # overflow as defined in note 2
  SRL_OV = isDivideOverflow(TOK_10_8_Dreg, TOK_3_0_Wreg);
  
  # Note: this implementation is not iterative, like the actual op.
  # Rather, it will decompile accurately and emulate correctly using the Sleigh divide support.
  local div:4 = TOK_10_8_Dreg s/ sext(TOK_3_0_Wreg);
  local rem:4 = TOK_10_8_Dreg s% sext(TOK_3_0_Wreg);
  W0 = div:2;
  W1 = rem:2;

  testSRL_N     ( W1 );
  testSRL_Z     ( W1 );

  # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis
  SRL_C  = 0;
}

:div.sd  TOK_10_8_Dregn,TOK_3_0_Wreg is
         OP_23_20=0xD & OP_19_16=0x8 & OP_15=0x0 &
         TOK_10_8_Dreg & TOK_10_8_Dregn & OP_7=0 & TOK_W=1 & OP_5_4=0x0 & TOK_3_0_Wreg {

  # overflow as defined in note 2
  SRL_OV = isDivideOverflow(TOK_10_8_Dreg, TOK_3_0_Wreg);

  local div:4 = pic30_div(TOK_10_8_Dreg,TOK_3_0_Wreg);
  local rem:4 = pic30_rem(TOK_10_8_Dreg,TOK_3_0_Wreg);
  
  W0 = div:2;
  W1 = rem:2;

  testSRL_N     ( W1 );
  testSRL_Z     ( W1 );

  # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis
  SRL_C  = 0;
}


:repeat" 0x11 div.uw"   TOK_10_7_Wreg,TOK_3_0_Wreg is
          OP_31_0=0x090011;
          OP_23_20=0xD & OP_19_16=0x8 & OP_15=0x1 & 
          TOK_10_7_Wreg & TOK_W=0 & OP_5_4=0x0 & TOK_3_0_Wreg {

  # Note: this implementation is not iterative, like the actual op.
  # Rather, it will decompile accurately and emulate correctly using the Sleigh divide support.
  local div:2 = zext(TOK_10_7_Wreg) / zext(TOK_3_0_Wreg);
  local rem:2 = zext(TOK_10_7_Wreg) % zext(TOK_3_0_Wreg);

  W0 = div:1;
  W1 = rem:1;

  testSRL_N     ( W1 );

  # overflow as defined in note 2
  SRL_OV = 0;

  testSRL_Z     ( W1 );

  # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis
  SRL_C  = 0;
} 

:div.uw   TOK_10_7_Wreg,TOK_3_0_Wreg is
          OP_23_20=0xD & OP_19_16=0x8 & OP_15=0x1 & 
          TOK_10_7_Wreg & TOK_W=0 & OP_5_4=0x0 & TOK_3_0_Wreg {
  local div:2 = pic30_div(TOK_10_7_Wreg,TOK_3_0_Wreg);
  local rem:2 = pic30_rem(TOK_10_7_Wreg,TOK_3_0_Wreg);

  W0 = div;
  W1 = rem;

  testSRL_N     ( W1 );

  # overflow as defined in note 2
  SRL_OV = 0;

  testSRL_Z     ( W1 );

  # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis
  SRL_C  = 0;
} 

:repeat" 0x11 div.ud"  TOK_10_8_Dregn,TOK_3_0_Wreg is
         OP_31_0=0x090011;
         OP_23_20=0xD & OP_19_16=0x8 & OP_15=0x1 &
         TOK_10_8_Dreg & TOK_10_8_Dregn & OP_7=0 & TOK_W=1 & OP_5_4=0x0 & TOK_3_0_Wreg {

  # overflow as defined in note 2
  SRL_OV = isDivideOverflow(TOK_10_8_Dreg, TOK_3_0_Wreg);
  
  # Note: this implementation is not iterative, like the actual op.
  # Rather, it will decompile accurately and emulate correctly using the Sleigh divide support.
  local div:4 = TOK_10_8_Dreg / sext(TOK_3_0_Wreg);
  local rem:4 = TOK_10_8_Dreg % sext(TOK_3_0_Wreg);
  W0 = div:2;
  W1 = rem:2;

  testSRL_N     ( W1 );
  testSRL_Z     ( W1 );

  # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis
  SRL_C  = 0;
}

:div.ud  TOK_10_8_Dregn,TOK_3_0_Wreg is
         OP_23_20=0xD & OP_19_16=0x8 & OP_15=0x1 &
         TOK_10_8_Dreg & TOK_10_8_Dregn & OP_7=0 & TOK_W=1 & OP_5_4=0x0 & TOK_3_0_Wreg {

  # overflow as defined in note 2
  SRL_OV = isDivideOverflow(TOK_10_8_Dreg, TOK_3_0_Wreg);
  
  local div:4 = pic30_div(TOK_10_8_Dreg,TOK_3_0_Wreg);
  local rem:4 = pic30_rem(TOK_10_8_Dreg,TOK_3_0_Wreg);
  W0 = div:2;
  W1 = rem:2;


  testSRL_N     ( W1 );
  testSRL_Z     ( W1 );

  # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis
  SRL_C  = 0;
}


@if defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) || defined(dsPIC33C)
:repeat" 0x11 divf"  TOK_14_11_Wreg,TOK_3_0_Wreg is
         OP_31_0=0x090011;
         OP_23_20=0xD & OP_19_16=0x9 & OP_15=0x0 &
         TOK_14_11_Wreg & OP_10_8=0x0 & OP_7_4=0x0 & TOK_3_0_Wreg {

  dividend:4 	= (sext(TOK_14_11_Wreg) << 16);
  local tmp0:4 		= dividend s/ sext(TOK_3_0_Wreg);
  W0 			= tmp0:2;
  local tmp1 			= dividend s% sext(TOK_3_0_Wreg);
  W1 			= tmp1:2;

  testSRL_N     ( W1 );

  # overflow as defined in note 1
  SRL_OV = (TOK_14_11_Wreg s>= TOK_3_0_Wreg);

  testSRL_Z     ( W1 );

  # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis
  SRL_C  = 0;
}

:divf  TOK_14_11_Wreg,TOK_3_0_Wreg is
         OP_23_20=0xD & OP_19_16=0x9 & OP_15=0x0 &
         TOK_14_11_Wreg & OP_10_8=0x0 & OP_7_4=0x0 & TOK_3_0_Wreg {

  # Note: this implementation is not iterative, like the actual op.
  # Rather, it will decompile accurately and emulate correctly using the Sleigh divide support.
  local dividend:4 	= (sext(TOK_14_11_Wreg) << 16);
  local tmp0:4 		= pic30_div(dividend,TOK_3_0_Wreg);
  W0 			= tmp0:2;
  local tmp1:4 		= pic30_rem(dividend,TOK_3_0_Wreg);
  W1 			= tmp1:2;

  testSRL_N     ( W1 );

  # overflow as defined in note 1
  SRL_OV = (TOK_14_11_Wreg s>= TOK_3_0_Wreg);

  testSRL_Z     ( W1 );

  # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis
  SRL_C  = 0;
}
@endif


@if defined(dsPIC33C)
define pcodeop pic30_fdiv;
define pcodeop pic30_frem;

:divf2  TOK_14_11_Wreg,TOK_3_0_Wreg is
         OP_23_20=0xD & OP_19_16=0x9 & OP_15=0x0 &
         TOK_14_11_Wreg & OP_10_8=0x0 & OP_7_4=0x2 & TOK_3_0_Wreg & TOK_14_11_Wregn {

  # Note: this implementation is not iterative, like the actual op.
  # Rather, it will decompile accurately and emulate correctly using the Sleigh divide support.
  local dividend:4 	= (sext(TOK_14_11_Wreg) << 16);
  local tmp0:4 		= pic30_fdiv(dividend,TOK_3_0_Wreg,TOK_14_11_Wregn);
  local tmp1:4 		= pic30_frem(dividend,TOK_3_0_Wreg,TOK_14_11_Wregn);
  TOK_14_11_Wregn 	= tmp0:2;
  TOK_14_11_Wreg	= tmp1:2;

  testSRL_N     ( TOK_14_11_Wreg );

  # overflow as defined in note 1
  SRL_OV = (TOK_14_11_Wreg s>= TOK_3_0_Wreg);

  testSRL_Z     ( TOK_14_11_Wreg );

  # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis
  SRL_C  = 0;
}

define pcodeop pic30_div2;
define pcodeop pic30_rem2;
:div2.sw   TOK_10_7_Wreg,TOK_3_0_Wreg is
          OP_23_20=0xD & OP_19_16=0x8 & OP_15=0x0 & TOK_10_7_Wreg & TOK_10_7_Wregp & TOK_W=0 & OP_5_4=0x2 & TOK_3_0_Wreg {
  local div:2 = pic30_div(TOK_10_7_Wreg,TOK_3_0_Wreg);
  local rem:2 = pic30_rem(TOK_10_7_Wreg,TOK_3_0_Wreg);

  TOK_10_7_Wreg = div;
  TOK_10_7_Wregp = rem;
  
  testSRL_N     ( TOK_10_7_Wregp );
  # overflow as defined in note 2
  SRL_OV = (TOK_10_7_Wreg == 0x8000) && (TOK_3_0_Wreg == 0xFFFF);
  testSRL_Z     ( TOK_10_7_Wregp );

  # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis
  SRL_C  = 0;
}

:div2.sd  TOK_10_8_Dregn,TOK_3_0_Wreg is
         OP_23_20=0xD & OP_19_16=0x8 & OP_15=0x0 &
         TOK_10_8_Dreg & TOK_10_8_Dregn & OP_7=0 & TOK_W=1 & OP_5_4=0x2 & TOK_3_0_Wreg {

  # overflow as defined in note 2
  SRL_OV = isDivideOverflow(TOK_10_8_Dreg, TOK_3_0_Wreg);

  local div:2 = pic30_div2(TOK_10_8_Dreg,TOK_3_0_Wreg);
  local rem:2 = pic30_rem2(TOK_10_8_Dreg,TOK_3_0_Wreg);
  
  TOK_10_8_Dreg = (zext(rem) << 16) + zext(div);

  testSRL_N     ( rem );
  testSRL_Z     ( rem );

  # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis
  SRL_C  = 0;
}


:div2.uw   TOK_10_7_Wreg,TOK_3_0_Wreg is
          OP_23_20=0xD & OP_19_16=0x8 & OP_15=0x1 & TOK_10_7_Wreg & TOK_10_7_Wregp & TOK_W=0 & OP_5_4=0x2 & TOK_3_0_Wreg {
  local div:2 = pic30_div(TOK_10_7_Wreg,TOK_3_0_Wreg);
  local rem:2 = pic30_rem(TOK_10_7_Wreg,TOK_3_0_Wreg);

  TOK_10_7_Wreg = div;
  TOK_10_7_Wregp = rem;
  
  testSRL_N     ( TOK_10_7_Wregp );
  # overflow as defined in note 2
  SRL_OV = 0;
  testSRL_Z     ( TOK_10_7_Wregp );

  # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis
  SRL_C  = 0;
}

:div2.ud  TOK_10_8_Dregn,TOK_3_0_Wreg is
         OP_23_20=0xD & OP_19_16=0x8 & OP_15=0x1 &
         TOK_10_8_Dreg & TOK_10_8_Dregn & OP_7=0 & TOK_W=1 & OP_5_4=0x2 & TOK_3_0_Wreg {

  # overflow as defined in note 2
  SRL_OV = isDivideOverflow(TOK_10_8_Dreg, TOK_3_0_Wreg);

  local div:2 = pic30_div2(TOK_10_8_Dreg,TOK_3_0_Wreg);
  local rem:2 = pic30_rem2(TOK_10_8_Dreg,TOK_3_0_Wreg);
  
  TOK_10_8_Dreg = (zext(rem) << 16) + zext(div);

  testSRL_N     ( rem );
  testSRL_Z     ( rem );

  # Carry is modified, but modification is not defined, just assign to 0 for data flow analysis
  SRL_C  = 0;
}
@endif


@if defined(dsPIC30F) || defined(dsPIC33F) 
:do k14_t,n16_t is OP_23_20=0x0 & OP_19_16=0x8 & OP_15_14=0x0 & k14_t ;
                   OP_23_20=0x0 & OP_19_16=0x0 & n16_t & WordInstNext
                   [ blockEnd=1; globalset(n16_t,blockEnd);] 
{
  DCOUNT_SHADOW  = DCOUNT;
  DCOUNT         = k14_t + 1;
  DOEND_SHADOW   = DOEND;
  DOEND          = &n16_t;
  DOSTART_SHADOW = DOSTART;
  DOSTART        = WordInstNext;
}
@endif


@if defined(dsPIC33E) || defined(dsPIC33C)
:do k15_t,n16_t is OP_23_20=0x0 & OP_19_16=0x8 & OP_15=0x0 & k15_t ;
                   OP_23_20=0x0 & OP_19_16=0x0 &             n16_t & WordInstNext
                   [ blockEnd=1; globalset(n16_t,blockEnd); ]
{
  # stack 4 levels deep but we don't enforce this
  DL:2 = zext(CORCON_DL);
  *[register]:2 (&:2 DCOUNT  + DL*2) = k15_t + 1;
  *[register]:3 (&:2 DOEND   + DL*2) = &n16_t;
  *[register]:3 (&:2 DOSTART + DL*2) = WordInstNext;
  CORCON_DL      = CORCON_DL + 1;
}
@endif


@if defined(dsPIC30F) || defined(dsPIC33F) 
:do Wns_t,n16_t is OP_23_20=0x0 & OP_19_16=0x8 & OP_15_12=0x8 & OP_11_8=0x0 & OP_7_4=0x0 & Wns_t ;
                   OP_23_20=0x0 & OP_19_16=0x0 & n16_t & WordInstNext
                   [ blockEnd=1; globalset(n16_t,blockEnd); ]
{
  DCOUNT_SHADOW  = DCOUNT;
  DCOUNT         = Wns_t + 1;
  DOEND_SHADOW   = DOEND;
  DOEND          = &n16_t;
  DOSTART_SHADOW = DOSTART;
  DOSTART        = WordInstNext;
}
@endif


@if defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) || defined(dsPIC33C)
:ed WmWm_t,ACCA_t,Wx_t,Wy_t,Wxd_t is 
     OP_23_20=0xF & OP_19_18=0x0 & WmWm_t & ACCA_t & OP_14=0x1 &
     Wxd_t & OP_11_10=0x0 & Wx_t & Wy_t & OP_1_0=0x3 {

# Note: MAC-class instruction

  # (Wm)*(Wm) -> ACCA
  ACCA = WmWm_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx] - [Wy]) -> Wxd
  # (Wx) +/- kx -> Wx
  # (Wy) +/- ky -> Wy
  Wxd_t = Wx_t - Wy_t;
}


:ed WmWm_t,ACCB_t,Wx_t,Wy_t,Wxd_t is 
     OP_23_20=0xF & OP_19_18=0x0 & WmWm_t & ACCB_t & OP_14=0x1 &
     Wxd_t & OP_11_10=0x0 & Wx_t & Wy_t & OP_1_0=0x3 {

# Note: MAC-class instruction

  # (Wm)*(Wm) -> ACCB
  ACCB = WmWm_t;
  testSRH_OB();
  testSRH_SB();

  # ([Wx] - [Wy]) -> Wxd
  # (Wx) +/- kx -> Wx
  # (Wy) +/- ky -> Wy
  Wxd_t = Wx_t - Wy_t;
}
@endif


@if defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) || defined(dsPIC33C)
:edac WmWm_t,ACCA_t,Wx_t,Wy_t,Wxd_t is 
     OP_23_20=0xF & OP_19_18=0x0 & WmWm_t & ACCA_t & OP_14=0x1 &
     Wxd_t & OP_11_10=0x0 & Wx_t & Wy_t & OP_1_0=0x2 {

# Note: MAC-class instruction

  # ACCA + (Wm)*(Wm) -> ACCA
  ACCA = ACCA + WmWm_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx] - [Wy]) -> Wxd
  # (Wx) +/- kx -> Wx
  # (Wy) +/- ky -> Wy
  Wxd_t = Wx_t - Wy_t;
}


:edac WmWm_t,ACCB_t,Wx_t,Wy_t,Wxd_t is 
     OP_23_20=0xF & OP_19_18=0x0 & WmWm_t & ACCB_t & OP_14=0x1 &
     Wxd_t & OP_11_10=0x0 & Wx_t & Wy_t & OP_1_0=0x2 {

# Note: MAC-class instruction

  # ACCB + (Wm)*(Wm) -> ACCB
  ACCB = ACCB + WmWm_t;
  testSRH_OB();
  testSRH_SB();

  # ([Wx] - [Wy]) -> Wxd
  # (Wx) +/- kx -> Wx
  # (Wy) +/- ky -> Wy
  Wxd_t = Wx_t - Wy_t;
}
@endif


:exch Wns_t,Wnd_t is
  OP_23_20=0xF & OP_19_16=0xD & OP_15_12=0x0 & OP_11=0x0 & Wnd_t & OP_6_4=0x0 & Wns_t {

  tmp:2 = Wnd_t;
  Wnd_t = Wns_t;
  Wns_t = tmp;
}


# OP_23_20=0x0 & OP_19_16=0x0 & OP_15_12=0x0 & OP_11_8=0x0 & OP_7_4=0x0 & OP_3_0=0x0 {
:fbcl Ws_t,Wnd_t is OP_23_20=0xD & OP_19_16=0xF & OP_15_12=0x0 & OP_11=0x0 & Wnd_t & $(WSconstraint) & Ws_t {

  local src = Ws_t;
  
  sign:2 	= src & 0x8000;
  temp:2 	= src << 1;
  shift:2 	= 0;

  <while>
    if !( (shift < 15) && ((temp & 0x8000) == sign) ) goto <done>;
      temp 	= temp << 1;
      shift = shift + 1;
  goto <while>;

  <done>

  SRL_C = (shift == 15);
  Wnd_t = -shift;
}

# TODO: locate encoding details for FEX instruction 
# :fex

:ff1l Ws_t,Wnd_t is OP_23_20=0xC & OP_19_16=0xF & OP_15_12=0x8 & OP_11=0x0 & Wnd_t & $(WSconstraint) & Ws_t {

  temp:2 	= Ws_t;
  shift:2 	= 1;

  <while>
    if !( (shift < 17) && ((temp & 0x8000) == 0) ) goto <done>;
      temp 	= temp << 1;
      shift = shift + 1;
  goto <while>;

  <done>

  # If (Shift == Max_Shift)
  #   C = 1
  #   0 (Wnd)
  # Else
  #   C = 0
  #   Shift (Wnd)
  #
  SRL_C = (shift == 17);
  Wnd_t = shift * zext(!SRL_C);
}


:ff1r Ws_t,Wnd_t is OP_23_20=0xC & OP_19_16=0xF & OP_15_12=0x0 & OP_11=0x0 & Wnd_t & $(WSconstraint) & Ws_t {

  temp:2 	= Ws_t;
  shift:2 	= 1;

  <while>
    if !( (shift < 17) && ((temp & 0x0001) == 0) ) goto <done>;
      temp 	= temp >> 1;
      shift = shift + 1;
  goto <while>;

  <done>

  # If (Shift == Max_Shift)
  #   C = 1
  #   0 (Wnd)
  # Else
  #   C = 0
  #   Shift (Wnd)
  #
  SRL_C = (shift == 17);
  Wnd_t = shift * zext(!SRL_C);
}


@if defined(dsPIC33C)
define pcodeop force_data_range;

:flim Wbds_t, Ws_t is OP_23_16=0xE4 & OP_15=0x0 & OP_10_7=0x0 & Wbds_t & Ws_t {
  force_data_range(Ws_t, Wbds_t);
}

:flim.v Wbds_t, Ws_t, Wnd_t is OP_23_16=0xE5 & OP_15=1 & Wnd_t & Wbds_t & Ws_t{
  Wnd_t = force_data_range(Ws_t, Wbds_t);
}
@endif


:goto  dest24_t is ( OP_23_20=0x0 & OP_19_16=0x4 & OP_0=0x0 ;
                     OP_23_20=0x0 & OP_19_16=0x0 & OP_15_12=0x0 & OP_11_8=0x0 & OP_7=0x0 ) & dest24_t {

  goto dest24_t;
} 


@if defined(PIC24F) || defined(PIC24H) || defined(dsPIC30F) || defined(dsPIC33F) 
:goto  WnDest_t is OP_23_20=0x0 & OP_19_16=0x1 & OP_15_12=0x4 & OP_11_8=0x0 & OP_7_4=0x0 & WnDest_t {

  goto [WnDest_t];
} 
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:goto  WnDest_t is OP_23_20=0x0 & OP_19_16=0x1 & OP_15_12=0x0 & OP_11_8=0x4 & OP_7_4=0x0 & WnDest_t {

  goto [WnDest_t];
} 
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:goto.l  WnWn1_t is OP_23_20=0x0 & OP_19_16=0x1 & OP_15=0x1 & WnWn1_t & OP_10_8=0x4 & OP_7_4=0x0 {

  goto [WnWn1_t];
} 
@endif


:inc.w   f13_t^WREG_t is OP_23_20=0xE & OP_19_16=0xC & OP_15=0 & WREG_t & f13_t {

  local src = f13_t;
  local one:2 = 1;
  addflags( src, one );

  WREG_t =       src + one;

  testSRL_N     ( WREG_t );
  testSRL_Z     ( WREG_t );
  testSRH_DCword( WREG_t );
}


:inc.b f13byte_t^WREGbyte_t is OP_23_20=0xE & OP_19_16=0xC & OP_15=0 & WREGbyte_t & f13byte_t {

  local src = f13byte_t;
  local one:1 = 1;
  addflags( src, one );

  WREGbyte_t =   src + one;

  testSRL_N     ( WREGbyte_t );
  testSRL_Z     ( WREGbyte_t );
  testSRH_DCbyte( WREGbyte_t );
}


:inc.w   Ws_t,Wd_t is OP_23_20=0xE & OP_19_16=0x8 & OP_15=0x0 & TOK_B=0 & $(WDconstraint) & Wd_t & $(WSconstraint) & Ws_t {

  local src = Ws_t;
  local one:2 = 1;
  addflags( src, one );

  local result = src + one;
  build Wd_t;
  Wd_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCword( result );
} 

:inc.b  Wsbyte_t,Wdbyte_t is OP_23_20=0xE & OP_19_16=0x8 & OP_15=0x0 & TOK_B=1  & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & Wsbyte_t {

  local src = Wsbyte_t;
  local one:1 = 1;
  addflags( src, one );

  local result = src + one;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCbyte( result );
} 


:inc2.w   f13_t^WREG_t is OP_23_16=0xEC & OP_15=1 & WREG_t & f13_t {

  local src = f13_t;
  local two:2 = 2;
  addflags( src,  two );

  WREG_t =       src + two;

  testSRL_N     ( WREG_t );
  testSRL_Z     ( WREG_t );
  testSRH_DCword( WREG_t );
}


:inc2.b f13byte_t^WREGbyte_t is OP_23_16=0xEC & OP_15=1 & WREGbyte_t & f13byte_t {

  local src = f13byte_t;
  local two:1 = 2;
  addflags( src,  two );

  WREGbyte_t =   src + two;

  testSRL_N     ( WREGbyte_t );
  testSRL_Z     ( WREGbyte_t );
  testSRH_DCbyte( WREGbyte_t );
}


:inc2.w   Ws_t,Wd_t is OP_23_16=0xE8 & OP_15=0x1 & TOK_B=0 & $(WDconstraint) & Wd_t & $(WSconstraint) & Ws_t {

  local src = Ws_t;
  local two:2 = 2;
  addflags( src, two );

  local result = src + two;
  build Wd_t;
  Wd_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCword( result );
} 

:inc2.b  Wsbyte_t,Wdbyte_t is OP_23_16=0xE8 & OP_15=0x1 & TOK_B=1 & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & Wsbyte_t {

  local src = Wsbyte_t;
  local two:1 = 2;
  addflags( src, two );

  local result = src + two;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCbyte( result );
} 


:ior.w   f13_t^WREG_t is OP_23_20=0xB & OP_19_16=0x7 & OP_15=0 & WREG_t & f13_t {

  WREG_t =       f13_t | W0;

  testSRL_N     ( WREG_t );
  testSRL_Z     ( WREG_t );
}


:ior.b f13byte_t^WREGbyte_t is OP_23_20=0xB & OP_19_16=0x7 & OP_15=0 & WREGbyte_t & f13byte_t {

  WREGbyte_t =   f13byte_t | W0byte;

  testSRL_N     ( WREGbyte_t );
  testSRL_Z     ( WREGbyte_t );
}


:ior.w   k10_t,Wn_t is OP_23_20=0xB & OP_19_16=0x3 & OP_15=0 & k10_t & Wn_t {

  Wn_t =         k10_t | Wn_t;

  testSRL_N     ( Wn_t );
  testSRL_Z     ( Wn_t );
} 


:ior.b   k10byte_t,Wnbyte_t is OP_23_20=0xB & OP_19_16=0x3 & OP_15=0 & k10byte_t & Wnbyte_t {

  Wnbyte_t =     k10byte_t | Wnbyte_t;

  testSRL_N     ( Wnbyte_t );
  testSRL_Z     ( Wnbyte_t );
}


:ior.w   Wb_t,k5_t,Wd_t is OP_23_20=0x7 & OP_19=0x0 & OP_6_5=0x3 & Wb_t & $(WDconstraint) & Wd_t & k5_t {

  local result =         k5_t | Wb_t;
  build Wd_t;
  Wd_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
} 


:ior.b  Wbbyte_t,k5byte_t,Wdbyte_t is
        OP_23_20=0x7 & OP_19=0x0 & OP_6_5=0x3 & Wbbyte_t & $(WDconstraint) & Wdbyte_t & k5byte_t {

  local result =     k5byte_t | Wbbyte_t;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
} 


:ior.w   Wb_t,Ws_t,Wd_t is OP_23_20=0x7 & OP_19=0x0 & TOK_B=0 & Wb_t & $(WDconstraint) & Wd_t & $(WSconstraint) & Ws_t {

  local result = Wb_t | Ws_t;
  build Wd_t;
  Wd_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
} 

:ior.b  Wbbyte_t,Wsbyte_t,Wdbyte_t is OP_23_20=0x7 & OP_19=0x0 & TOK_B=1 & Wbbyte_t & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & Wsbyte_t {

  local result = Wbbyte_t | Wsbyte_t;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
} 


@if defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) || defined(dsPIC33C)
:lac WsWRO_t^r4_t,ACCA_t is OP_23_20=0xC & OP_19_16=0xA & ACCA_t & r4_t & WsWRO_t {

  ACCA = (sext(WsWRO_t) << (16 - r4_t));
  testSRH_OA();
  testSRH_SA();
} 

:lac WsWRO_t^r4_t,ACCB_t is OP_23_20=0xC & OP_19_16=0xA & ACCB_t & r4_t & WsWRO_t {

  ACCB = (sext(WsWRO_t) << (16 - r4_t));
  testSRH_OB();
  testSRH_SB();
} 
@endif


@if defined(dsPIC33C)
:lac.d Wsd_t^r4_t,ACCA_t is OP_23_16=0xDB & OP_14_11=0x0 & ACCA_t & r4_t & Wsd_t {

  ACCA = (sext(Wsd_t) << (16 - r4_t));
  testSRH_OA();
  testSRH_SA();
} 

:lac.d Wsd_t^r4_t,ACCB_t is OP_23_16=0xDB & OP_14_11=0x0 & ACCB_t & r4_t & Wsd_t {

  ACCB = (sext(Wsd_t) << (16 - r4_t));
  testSRH_OB();
  testSRH_SB();
} 
@endif


@if defined(dsPIC33C)
PSV_t: Ws_t is Ws_t {
	local psv_addr = (Ws_t & 0xf7 ) + (DSRPAG & 0xff) << 0xf;
	export *[rom]:3 psv_addr;
}

EDS_t: Wdpp_t is Wdpp_t {
	local eds_addr = (Wdpp_t & 0xf7 ) + (DSWPAG & 0xff) << 0xf;
	export *[rom]:2 eds_addr;
}

define pcodeop loadslave;
:ldslv PSV_t, EDS_t, k13_12_t is OP_23_16=0x03 & OP_15_14=0x0 & OP_11=0 & k13_12_t & EDS_t & PSV_t {
  EDS_t = loadslave(PSV_t, k13_12_t);
}
@endif


@if defined(PIC24F) || defined(PIC24H) || defined(dsPIC30F) || defined(dsPIC33F) 
:lnk  k14_t is OP_23_20=0xF & OP_19_16=0xA & OP_15_14=0x0 & k14_t & OP_0=0x0 {

  *[ram]:2 W15 = W14;
  W15 = W15 + 2;

  W14 = W15;
  W15 = W15 + k14_t;
} 
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:lnk  k14_t is OP_23_20=0xF & OP_19_16=0xA & OP_15_14=0x0 & k14_t & OP_0=0x0 {

  *[ram]:2 W15 = W14;
  W15 = W15 + 2;

  W14 = W15;
  CORCON_SFA = 1;
  W15 = W15 + k14_t;
} 
@endif


:lsr.w   f13_t^WREG_t is OP_23_20=0xD & OP_19_16=0x5 & OP_15=0 & WREG_t & f13_t {

  local src = f13_t;
  SRL_C = ( src & 0x0001 ) != 0;

  WREG_t =       src >> 1;

  testSRL_N     ( WREG_t );
  testSRL_Z     ( WREG_t );
}


:lsr.b f13byte_t^WREGbyte_t is OP_23_20=0xD & OP_19_16=0x5 & OP_15=0 & WREGbyte_t & f13byte_t {

  local src = f13byte_t;
  SRL_C = ( src & 0x01 ) != 0;

  WREGbyte_t =   src >> 1;

  testSRL_N     ( WREGbyte_t );
  testSRL_Z     ( WREGbyte_t );
}


:lsr.w   Ws_t,Wd_t is OP_23_20=0xD & OP_19_16=0x1 & OP_15=0x0 & TOK_B=0 & $(WDconstraint) & Wd_t & $(WSconstraint) & Ws_t {

  local src = Ws_t;
  SRL_C = ( src & 0x0001 ) != 0;

  local result = src >> 1;
  build Wd_t;
  Wd_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
} 

:lsr.b  Wsbyte_t,Wdbyte_t is OP_23_20=0xD & OP_19_16=0x1 & OP_15=0x0 & TOK_B=1 & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & Wsbyte_t {

  local src = Wsbyte_t;
  SRL_C = ( src & 0x01 ) != 0;

  local result = src >> 1;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N     ( Wdbyte_t );
  testSRL_Z     ( Wdbyte_t );
} 


:lsr.w   Wbd_t,k4_t,Wnd_t is OP_23_20=0xD & OP_19_16=0xE & OP_15=0x0 & OP_6_4=0x4 & Wbd_t & Wnd_t & k4_t {

  Wnd_t = Wbd_t >> k4_t;

  testSRL_N     ( Wnd_t );
  testSRL_Z     ( Wnd_t );
} 


:lsr.w  Wbd_t,Wns_t,Wnd_t is OP_23_20=0xD & OP_19_16=0xE & OP_15=0x0 & OP_6_4=0x0 & Wbd_t & Wnd_t & Wns_t {

  Wnd_t = Wbd_t >> ( Wns_t & 0x001F );

  testSRL_N     ( Wnd_t );
  testSRL_Z     ( Wnd_t );
} 


@if defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) || defined(dsPIC33C)
##
##
## ACCA series
##
##

:mac WmWn_t,ACCA_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 & TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCA + (Wm)*(Wn) -> ACCA
  ACCA = ACCA + WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
#  AWB_t = ACCBH;
} 


:mac WmWn_t,ACCA_t^AWB_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCA + (Wm)*(Wn) -> ACCA
  ACCA = ACCA + WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
  AWB_t = ACCBH;
} 


:mac WmWn_t,ACCA_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 &                    TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCA + (Wm)*(Wn) -> ACCA
  ACCA = ACCA + WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
#  AWB_t = ACCBH;
} 


:mac WmWn_t,ACCA_t^Wy_t^Wyd_t^AWB_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 &  
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCA + (Wm)*(Wn) -> ACCA
  ACCA = ACCA + WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
  AWB_t = ACCBH;
} 


:mac WmWn_t,ACCA_t^Wx_t^Wxd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x0 &
                        TOK_5_2_jjjj=0x4 & TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCA + (Wm)*(Wn) -> ACCA
  ACCA = ACCA + WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
#  AWB_t = ACCBH;
} 


:mac WmWn_t,ACCA_t^Wx_t^Wxd_t^AWB_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x0 &
                        TOK_5_2_jjjj=0x4 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCA + (Wm)*(Wn) -> ACCA
  ACCA = ACCA + WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
  AWB_t = ACCBH;
} 


:mac WmWn_t,ACCA_t^Wx_t^Wxd_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x0 &
                                           TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCA + (Wm)*(Wn) -> ACCA
  ACCA = ACCA + WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
#  AWB_t = ACCBH;
} 


:mac WmWn_t,ACCA_t^Wx_t^Wxd_t^Wy_t^Wyd_t^AWB_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x0 &
     
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCA + (Wm)*(Wn) -> ACCA
  ACCA = ACCA + WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
  AWB_t = ACCBH;
} 


##
##
## ACCB series
##
##

:mac WmWn_t,ACCB_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 & TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCB + (Wm)*(Wn) -> ACCB
  ACCB = ACCB + WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
#  AWB_t = ACCAH;
} 


:mac WmWn_t,ACCB_t^AWB_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCB + (Wm)*(Wn) -> ACCB
  ACCB = ACCB + WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
  AWB_t = ACCAH;
} 


:mac WmWn_t,ACCB_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 &                    TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCB + (Wm)*(Wn) -> ACCB
  ACCB = ACCB + WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
#  AWB_t = ACCAH;
} 


:mac WmWn_t,ACCB_t^Wy_t^Wyd_t^AWB_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 &  
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCB + (Wm)*(Wn) -> ACCB
  ACCB = ACCB + WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
  AWB_t = ACCAH;
} 


:mac WmWn_t,ACCB_t^Wx_t^Wxd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x0 &
                        TOK_5_2_jjjj=0x4 & TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCB + (Wm)*(Wn) -> ACCB
  ACCB = ACCB + WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
#  AWB_t = ACCAH;
} 


:mac WmWn_t,ACCB_t^Wx_t^Wxd_t^AWB_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x0 &
                        TOK_5_2_jjjj=0x4 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCB + (Wm)*(Wn) -> ACCB
  ACCB = ACCB + WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
  AWB_t = ACCAH;
} 


:mac WmWn_t,ACCB_t^Wx_t^Wxd_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x0 &
                                           TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCB + (Wm)*(Wn) -> ACCB
  ACCB = ACCB + WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
#  AWB_t = ACCAH;
} 


:mac WmWn_t,ACCB_t^Wx_t^Wxd_t^Wy_t^Wyd_t^AWB_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x0 &
     
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCB + (Wm)*(Wn) -> ACCB
  ACCB = ACCB + WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
  AWB_t = ACCAH;
} 
@endif


@if defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) || defined(dsPIC33C)
##
##
## ACCA series
##
##

:mac WmWm_t,ACCA_t is 
     OP_23_20=0xF & OP_19_18=0x0 & WmWm_t & ACCA_t & OP_14=0x0 & OP_1_0=0x0 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 &
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # ACCA + (Wm)*(Wm) -> ACCA
  ACCA = ACCA + WmWm_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;
} 


:mac WmWm_t,ACCA_t^Wy_t^Wyd_t is 
     OP_23_20=0xF & OP_19_18=0x0 & WmWm_t & ACCA_t & OP_14=0x0 & OP_1_0=0x0 &
     TOK_9_6_iiii=0x4 &                    
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # ACCA + (Wm)*(Wm) -> ACCA
  ACCA = ACCA + WmWm_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;
} 


:mac WmWm_t,ACCA_t^Wx_t^Wxd_t is 
     OP_23_20=0xF & OP_19_18=0x0 & WmWm_t & ACCA_t & OP_14=0x0 & OP_1_0=0x0 &
                        TOK_5_2_jjjj=0x4 &
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # ACCA + (Wm)*(Wm) -> ACCA
  ACCA = ACCA + WmWm_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;
} 


:mac WmWm_t,ACCA_t^Wx_t^Wxd_t^Wy_t^Wyd_t is 
     OP_23_20=0xF & OP_19_18=0x0 & WmWm_t & ACCA_t & OP_14=0x0 & OP_1_0=0x0 &
                                           
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # ACCA + (Wm)*(Wm) -> ACCA
  ACCA = ACCA + WmWm_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;
} 


##
##
## ACCB series
##
##

:mac WmWm_t,ACCB_t is 
     OP_23_20=0xF & OP_19_18=0x0 & WmWm_t & ACCB_t & OP_14=0x0 & OP_1_0=0x0 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 &
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # ACCB + (Wm)*(Wm) -> ACCB
  ACCB = ACCB + WmWm_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;
} 


:mac WmWm_t,ACCB_t^Wy_t^Wyd_t is 
     OP_23_20=0xF & OP_19_18=0x0 & WmWm_t & ACCB_t & OP_14=0x0 & OP_1_0=0x0 &
     TOK_9_6_iiii=0x4 &                   
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # ACCB + (Wm)*(Wm) -> ACCB
  ACCB = ACCB + WmWm_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;
} 


:mac WmWm_t,ACCB_t^Wx_t^Wxd_t is 
     OP_23_20=0xF & OP_19_18=0x0 & WmWm_t & ACCB_t & OP_14=0x0 & OP_1_0=0x0 &
                        TOK_5_2_jjjj=0x4 &
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # ACCB + (Wm)*(Wm) -> ACCB
  ACCB = ACCB + WmWm_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;
} 


:mac WmWm_t,ACCB_t^Wx_t^Wxd_t^Wy_t^Wyd_t is 
     OP_23_20=0xF & OP_19_18=0x0 & WmWm_t & ACCB_t & OP_14=0x0 & OP_1_0=0x0 &
                                          
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # ACCB + (Wm)*(Wm) -> ACCB
  ACCB = ACCB + WmWm_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;
} 
@endif


@if defined(dsPIC33C)

:max ACCA_t is OP_23_16=0xCE & ACCA_t & OP_14_0=0x1000 {
  local val = ACCA_t - ACCB;
  ACCA_t = (ACCA)*zext(val s<= 0) + (ACCB)*zext(val s> 0);
  SRL_Z  = zext(val s<= 0);
  SRL_N  = 0;
  SRL_OV = 0;
}

:max ACCB_t is OP_23_16=0xCE & ACCB_t & OP_14_0=0x1000 {
  local val = ACCB_t - ACCA;
  ACCB_t = (ACCB)*zext(val s<= 0) + (ACCA)*zext(val s> 0);
  SRL_Z  = zext(val s<= 0);
  SRL_N  = 0;
  SRL_OV = 0;
}


:max.v ACCA_t, Ws_t is OP_23_16=0xCE & ACCA_t & OP_14_7=0x30 & Ws_t {
  local val = ACCA_t - ACCB;
  ACCA_t = (ACCA)*zext(val s<= 0) + (ACCB)*zext(val s> 0);
  Ws_t   = (val:2)*zext(val s> 0);
  SRL_Z  = zext(val s<= 0);
  SRL_N  = 0;
  SRL_OV = 0;
}

:max.v ACCB_t, Ws_t is OP_23_16=0xCE & ACCB_t & OP_14_7=0x30 & Ws_t {
  local val = ACCB_t - ACCA;
  ACCB_t = (ACCB)*zext(val s<= 0) + (ACCA)*zext(val s> 0);
  Ws_t   = (val:2)*zext(val s> 0);
  SRL_Z  = zext(val s<= 0);
  SRL_N  = 0;
  SRL_OV = 0;
}


:min ACCA_t is OP_23_16=0xCE & ACCA_t & OP_14_0=0x3000 {
  local val = ACCA_t - ACCB;
  ACCA_t = (ACCA)*zext(val s>= 0) + (ACCB)*zext(val s< 0);
  SRL_Z  = zext(val s>= 0);
  SRL_N  = zext(val s< 0);
  SRL_OV = 0;
}

:min ACCB_t is OP_23_16=0xCE & ACCB_t & OP_14_0=0x3000 {
  local val = ACCB_t - ACCA;
  ACCB_t = (ACCB)*zext(val s>= 0) + (ACCA)*zext(val s< 0);
  SRL_Z  = zext(val s>= 0);
  SRL_N  = zext(val s< 0);
  SRL_OV = 0;
}

:min.v ACCA_t, Ws_t is OP_23_16=0xCE & ACCA_t & OP_14_7=0x70 & Ws_t {
  local val = ACCA_t - ACCB;
  ACCA_t = (ACCA)*zext(val s>= 0) + (ACCB)*zext(val s< 0);
  Ws_t   = (val:2)*zext(val s< 0);
  SRL_Z  = zext(val s>= 0);
  SRL_N  = zext(val s< 0);
  SRL_OV = 0;
}

:min.v ACCB_t, Ws_t is OP_23_16=0xCE & ACCB_t & OP_14_7=0x70 & Ws_t {
  local val = ACCB_t - ACCA;
  ACCB_t = (ACCB)*zext(val s>= 0) + (ACCA)*zext(val s< 0);
  Ws_t   = (val:2)*zext(val s< 0);
  SRL_Z  = zext(val s>= 0);
  SRL_N  = zext(val s< 0);
  SRL_OV = 0;
}


:minz ACCA_t is OP_23_16=0xCE & ACCA_t & OP_14_0=0x3400 {
  if (SRL_Z == 0) goto inst_next;
  local val = ACCA_t - ACCB;
  ACCA_t = (ACCA)*zext(val s>= 0) + (ACCB)*zext(val s< 0);
  SRL_Z  = zext(val s>= 0);
  SRL_N  = zext(val s< 0);
  SRL_OV = 0;
}

:minz ACCB_t is OP_23_16=0xCE & ACCB_t & OP_14_0=0x3400 {
  if (SRL_Z == 0) goto inst_next;
  local val = ACCB_t - ACCA;
  ACCB_t = (ACCB)*zext(val s>= 0) + (ACCA)*zext(val s< 0);
  SRL_Z  = zext(val s>= 0);
  SRL_N  = zext(val s< 0);
  SRL_OV = 0;
}

:minz.v ACCA_t, Ws_t is OP_23_16=0xCE & ACCA_t & OP_14_7=0x78 & Ws_t {
  if (SRL_Z == 0) goto inst_next;
  local val = ACCA_t - ACCB;
  ACCA_t = (ACCA)*zext(val s>= 0) + (ACCB)*zext(val s< 0);
  Ws_t   = (val:2)*zext(val s< 0);
  SRL_Z  = zext(val s>= 0);
  SRL_N  = zext(val s< 0);
  SRL_OV = 0;
}

:minz.v ACCB_t, Ws_t is OP_23_16=0xCE & ACCB_t & OP_14_7=0x78 & Ws_t {
  if (SRL_Z == 0) goto inst_next;
  local val = ACCB_t - ACCA;
  ACCB_t = (ACCB)*zext(val s>= 0) + (ACCA)*zext(val s< 0);
  Ws_t   = (val:2)*zext(val s< 0);
  SRL_Z  = zext(val s>= 0);
  SRL_N  = zext(val s< 0);
  SRL_OV = 0;
}
@endif


:mov.w   f13_t^WREG_t is OP_23_20=0xB & OP_19_16=0xF & OP_15=1 & WREG_t & f13_t {

  WREG_t =       f13_t;

  testSRL_N     ( WREG_t );
  testSRL_Z     ( WREG_t );
}


:mov.b f13byte_t^WREGbyte_t is OP_23_20=0xB & OP_19_16=0xF & OP_15=1 & WREGbyte_t & f13byte_t {

  WREGbyte_t =   f13byte_t;

  testSRL_N     ( WREGbyte_t );
  testSRL_Z     ( WREGbyte_t );
}


:mov.w   WREG_W0_t,f13_t is OP_23_20=0xB & OP_19_16=0x7 & OP_15=1 & WREG_W0_t & OP_13=1 & f13_t {

  f13_t = WREG_W0_t;
}


:mov.b   WREG_W0byte_t,f13byte_t is OP_23_20=0xB & OP_19_16=0x7 & OP_15=1 & WREG_W0byte_t & OP_13=1 & f13byte_t {

  f13byte_t = WREG_W0byte_t;
}


:mov.w f15b_t,Wndb_t is OP_23_20=0x8 & OP_19=0x0 & f15b_t & Wndb_t {

  Wndb_t = f15b_t;
}


:mov.w Wns_t,f15b_t is OP_23_20=0x8 & OP_19=0x1 & f15b_t & Wns_t {

  f15b_t = Wns_t;
}


:mov.b TOK_k8c,Wndbyte_t is OP_23_20=0xB & OP_19_16=0x3 & OP_15_12=0xC & TOK_k8c & Wndbyte_t {

  Wndbyte_t = TOK_k8c;
}


:mov.w k16_t,Wndb_t is OP_23_20=0x2 & k16_t & Wndb_t {

  Wndb_t = k16_t;
}


:mov.w WsSlit10_t,Wnda_t is OP_23_20=0x9 & OP_19=0 & TOK_B=0 & WsSlit10_t & Wnda_t {

  Wnda_t = WsSlit10_t;
}

:mov.b WsSlit10byte_t,Wndabyte_t is OP_23_20=0x9 & OP_19=0 & TOK_B=1 & WsSlit10byte_t & Wndabyte_t {

  Wndabyte_t = WsSlit10byte_t;
}


:mov.w Wn_t,WdSlit10_t is OP_23_20=0x9 & OP_19=1 & TOK_B=0 & WdSlit10_t & Wn_t {

  WdSlit10_t = Wn_t;
}

:mov.b Wnbyte_t,WdSlit10byte_t is OP_23_20=0x9 & OP_19=1 & TOK_B=1 & WdSlit10byte_t & Wnbyte_t {

  WdSlit10byte_t = Wnbyte_t;
}


:mov.w movWs,movWd is OP_23_20=0x7 & OP_19=1 & TOK_B=0 & movWd & movWs {

  local result = movWs;
  build movWd;
  movWd = result;
}


:mov.b movWsbyte,movWdbyte is OP_23_20=0x7 & OP_19=1 & TOK_B=1 & movWdbyte & movWsbyte {

  local result = movWsbyte;
  build movWdbyte;
  movWdbyte = result;
}


:mov.d Wsd_t,Wndd_t is
  OP_23_20=0xB & OP_19_16=0xE & OP_15_12=0x0 & OP_11=0x0 & Wndd_t & OP_7=0x0 & $(WSconstraint) & Wsd_t {

  Wndd_t = Wsd_t;
}


:mov.d TOK_3_1_Dregn,Wdd_t is 
  OP_23_20=0xb & OP_19_16=0xe & OP_15_14=0x2 & OP_6_4=0x0 & TOK_3_1_Dreg & TOK_3_1_Dregn & OP_0=0 & $(WDconstraint) & Wdd_t { 
  
	local result = TOK_3_1_Dreg;	
	build Wdd_t;
	Wdd_t = result;
}


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
TOK_9_0_U_t: is TOK_9_0_U { export *[const]:2 TOK_9_0_U; }

:movpag TOK_9_0_U_t,DSRPAG is OP_23_20=0xF & OP_19_16=0xE & OP_15_12=0xC & TOK_11_10_PP=0 & TOK_9_0_U_t & DSRPAG {
  DSRPAG = TOK_9_0_U_t;
}

:movpag TOK_9_0_U_t,DSWPAG is OP_23_20=0xF & OP_19_16=0xE & OP_15_12=0xC & TOK_11_10_PP=1 & TOK_9_0_U_t & DSWPAG {
  DSWPAG = TOK_9_0_U_t;
}

:movpag TOK_9_0_U_t,TBLPAG is OP_23_20=0xF & OP_19_16=0xE & OP_15_12=0xC & TOK_11_10_PP=2 & TOK_9_0_U_t & TBLPAG {
  TBLPAG = TOK_9_0_U_t:1;
}

:movpag TOK_3_0_Wreg,DSRPAG is OP_23_20=0xF & OP_19_16=0xE & OP_15_12=0xD & TOK_11_10_PP=0 & OP_9_4=0x0 & TOK_3_0_Wreg & DSRPAG {
  DSRPAG = TOK_3_0_Wreg;
}
:movpag TOK_3_0_Wreg,DSWPAG is OP_23_20=0xF & OP_19_16=0xE & OP_15_12=0xD & TOK_11_10_PP=1 & OP_9_4=0x0 & TOK_3_0_Wreg & DSWPAG {
  DSWPAG = TOK_3_0_Wreg;
} 
:movpag TOK_3_0_Wreg,TBLPAG is OP_23_20=0xF & OP_19_16=0xE & OP_15_12=0xD & TOK_11_10_PP=2 & OP_9_4=0x0 & TOK_3_0_Wreg & TBLPAG {
  TBLPAG = TOK_3_0_Wreg:1;
} 
@endif 


@if defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) || defined(dsPIC33C)
##
##
## ACCA series
##
##

:movsac ACCA_t is 
     OP_23_20=0xC & OP_19_16=0x7 & ACCA_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 & TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
#  AWB_t = ACCBH;
} 


:movsac ACCA_t^AWB_t is 
     OP_23_20=0xC & OP_19_16=0x7 & ACCA_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
  AWB_t = ACCBH;
} 


:movsac ACCA_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19_16=0x7 & ACCA_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 &                    TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
#  AWB_t = ACCBH;
} 


:movsac ACCA_t^Wy_t^Wyd_t^AWB_t is 
     OP_23_20=0xC & OP_19_16=0x7 & ACCA_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 &  
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
  AWB_t = ACCBH;
} 


:movsac ACCA_t^Wx_t^Wxd_t is 
     OP_23_20=0xC & OP_19_16=0x7 & ACCA_t & OP_14=0x0 &
                        TOK_5_2_jjjj=0x4 & TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
#  AWB_t = ACCBH;
} 


:movsac ACCA_t^Wx_t^Wxd_t^AWB_t is 
     OP_23_20=0xC & OP_19_16=0x7 & ACCA_t & OP_14=0x0 &
                        TOK_5_2_jjjj=0x4 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
  AWB_t = ACCBH;
} 


:movsac ACCA_t^Wx_t^Wxd_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19_16=0x7 & ACCA_t & OP_14=0x0 &
                                           TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
#  AWB_t = ACCBH;
} 


:movsac ACCA_t^Wx_t^Wxd_t^Wy_t^Wyd_t^AWB_t is 
     OP_23_20=0xC & OP_19_16=0x7 & ACCA_t & OP_14=0x0 &
     
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
  AWB_t = ACCBH;
} 


##
##
## ACCB series
##
##

:movsac ACCB_t is 
     OP_23_20=0xC & OP_19_16=0x7 & ACCB_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 & TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
#  AWB_t = ACCAH;
} 


:movsac ACCB_t^AWB_t is 
     OP_23_20=0xC & OP_19_16=0x7 & ACCB_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
  AWB_t = ACCAH;
} 


:movsac ACCB_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19_16=0x7 & ACCB_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 &                    TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
#  AWB_t = ACCAH;
} 


:movsac ACCB_t^Wy_t^Wyd_t^AWB_t is 
     OP_23_20=0xC & OP_19_16=0x7 & ACCB_t & OP_14=0x0 &
     TOK_9_6_iiii=0x4 &  
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
  AWB_t = ACCAH;
} 


:movsac ACCB_t^Wx_t^Wxd_t is 
     OP_23_20=0xC & OP_19_16=0x7 & ACCB_t & OP_14=0x0 &
                        TOK_5_2_jjjj=0x4 & TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
#  AWB_t = ACCAH;
} 


:movsac ACCB_t^Wx_t^Wxd_t^AWB_t is 
     OP_23_20=0xC & OP_19_16=0x7 & ACCB_t & OP_14=0x0 &
                        TOK_5_2_jjjj=0x4 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
  AWB_t = ACCAH;
} 


:movsac ACCB_t^Wx_t^Wxd_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19_16=0x7 & ACCB_t & OP_14=0x0 &
                                           TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
#  AWB_t = ACCAH;
} 


:movsac ACCB_t^Wx_t^Wxd_t^Wy_t^Wyd_t^AWB_t is 
     OP_23_20=0xC & OP_19_16=0x7 & ACCB_t & OP_14=0x0 &
     
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
  AWB_t = ACCAH;
} 
@endif


@if defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) || defined(dsPIC33C)
:mpy WmWn_t,ACCA_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x0 & OP_1_0=0x3 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 &
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # (Wm)*(Wn) -> ACCA
  ACCA = WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;
} 


:mpy WmWn_t,ACCA_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x0 & OP_1_0=0x3 &
     TOK_9_6_iiii=0x4 &                    
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # (Wm)*(Wn) -> ACCA
  ACCA = WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;
} 


:mpy WmWn_t,ACCA_t^Wx_t^Wxd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x0 & OP_1_0=0x3 &
                        TOK_5_2_jjjj=0x4 &
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # (Wm)*(Wn) -> ACCA
  ACCA = WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;
} 


:mpy WmWn_t,ACCA_t^Wx_t^Wxd_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x0 & OP_1_0=0x3 &
                                           
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # (Wm)*(Wn) -> ACCA
  ACCA = WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;
} 


##
##
## ACCB series
##
##

:mpy WmWn_t,ACCB_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x0 & OP_1_0=0x3 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 &
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # (Wm)*(Wn) -> ACCB
  ACCB = WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;
} 


:mpy WmWn_t,ACCB_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x0 & OP_1_0=0x3 &
     TOK_9_6_iiii=0x4 &                   
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # (Wm)*(Wn) -> ACCB
  ACCB = WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;
} 


:mpy WmWn_t,ACCB_t^Wx_t^Wxd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x0 & OP_1_0=0x3 &
                        TOK_5_2_jjjj=0x4 &
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # (Wm)*(Wn) -> ACCB
  ACCB = WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;
} 


:mpy WmWn_t,ACCB_t^Wx_t^Wxd_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x0 & OP_1_0=0x3 &
                                          
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # (Wm)*(Wn) -> ACCB
  ACCB = WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;
} 
@endif


@if defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) || defined(dsPIC33C)
:mpy WmWm_t,ACCA_t is 
     OP_23_20=0xF & OP_19_18=0x0 & WmWm_t & ACCA_t & OP_14=0x0 & OP_1_0=0x1 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 &
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # (Wm)*(Wm) -> ACCA
  ACCA = WmWm_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;
} 


:mpy WmWm_t,ACCA_t^Wy_t^Wyd_t is 
     OP_23_20=0xF & OP_19_18=0x0 & WmWm_t & ACCA_t & OP_14=0x0 & OP_1_0=0x1 &
     TOK_9_6_iiii=0x4 &                    
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # (Wm)*(Wm) -> ACCA
  ACCA = WmWm_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;
} 


:mpy WmWm_t,ACCA_t^Wx_t^Wxd_t is 
     OP_23_20=0xF & OP_19_18=0x0 & WmWm_t & ACCA_t & OP_14=0x0 & OP_1_0=0x1 &
                        TOK_5_2_jjjj=0x4 &
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # (Wm)*(Wm) -> ACCA
  ACCA = WmWm_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;
} 


:mpy WmWm_t,ACCA_t^Wx_t^Wxd_t^Wy_t^Wyd_t is 
     OP_23_20=0xF & OP_19_18=0x0 & WmWm_t & ACCA_t & OP_14=0x0 & OP_1_0=0x1 &
                                           
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # (Wm)*(Wm) -> ACCA
  ACCA = WmWm_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;
} 


##
##
## ACCB series
##
##

:mpy WmWm_t,ACCB_t is 
     OP_23_20=0xF & OP_19_18=0x0 & WmWm_t & ACCB_t & OP_14=0x0 & OP_1_0=0x1 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 &
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # (Wm)*(Wm) -> ACCB
  ACCB = WmWm_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;
} 


:mpy WmWm_t,ACCB_t^Wy_t^Wyd_t is 
     OP_23_20=0xF & OP_19_18=0x0 & WmWm_t & ACCB_t & OP_14=0x0 & OP_1_0=0x1 &
     TOK_9_6_iiii=0x4 &                   
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # (Wm)*(Wm) -> ACCB
  ACCB = WmWm_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;
} 


:mpy WmWm_t,ACCB_t^Wx_t^Wxd_t is 
     OP_23_20=0xF & OP_19_18=0x0 & WmWm_t & ACCB_t & OP_14=0x0 & OP_1_0=0x1 &
                        TOK_5_2_jjjj=0x4 &
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # (Wm)*(Wm) -> ACCB
  ACCB = WmWm_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;
} 


:mpy WmWm_t,ACCB_t^Wx_t^Wxd_t^Wy_t^Wyd_t is 
     OP_23_20=0xF & OP_19_18=0x0 & WmWm_t & ACCB_t & OP_14=0x0 & OP_1_0=0x1 &
                                          
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # (Wm)*(Wm) -> ACCB
  ACCB = WmWm_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;
} 
@endif


@if defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) || defined(dsPIC33C)
:mpy.n WmWn_t,ACCA_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x1 & OP_1_0=0x3 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 &
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # -(Wm)*(Wn) -> ACCA
  ACCA = -WmWn_t;
  testSRH_OA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;
} 


:mpy.n WmWn_t,ACCA_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x1 & OP_1_0=0x3 &
     TOK_9_6_iiii=0x4 &                    
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # -(Wm)*(Wn) -> ACCA
  ACCA = -WmWn_t;
  testSRH_OA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;
} 


:mpy.n WmWn_t,ACCA_t^Wx_t^Wxd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x1 & OP_1_0=0x3 &
                        TOK_5_2_jjjj=0x4 &
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # -(Wm)*(Wn) -> ACCA
  ACCA = -WmWn_t;
  testSRH_OA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;
} 


:mpy.n WmWn_t,ACCA_t^Wx_t^Wxd_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x1 & OP_1_0=0x3 &
                                           
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # -(Wm)*(Wn) -> ACCA
  ACCA = -WmWn_t;
  testSRH_OA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;
} 


##
##
## ACCB series
##
##

:mpy.n WmWn_t,ACCB_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x1 & OP_1_0=0x3 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 &
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # -(Wm)*(Wn) -> ACCB
  ACCB = -WmWn_t;
  testSRH_OA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;
} 


:mpy.n WmWn_t,ACCB_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x1 & OP_1_0=0x3 &
     TOK_9_6_iiii=0x4 &                   
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # -(Wm)*(Wn) -> ACCB
  ACCB = -WmWn_t;
  testSRH_OA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;
} 


:mpy.n WmWn_t,ACCB_t^Wx_t^Wxd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x1 & OP_1_0=0x3 &
                        TOK_5_2_jjjj=0x4 &
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # -(Wm)*(Wn) -> ACCB
  ACCB = -WmWn_t;
  testSRH_OA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;
} 


:mpy.n WmWn_t,ACCB_t^Wx_t^Wxd_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x1 & OP_1_0=0x3 &
                                          
     Wxd_t & Wyd_t & Wx_t & Wy_t {

# Note: MAC-class instruction

  # -(Wm)*(Wn) -> ACCB
  ACCB = -WmWn_t;
  testSRH_OA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;
} 
@endif


@if defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) || defined(dsPIC33C)
:msc WmWn_t,ACCA_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x1 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 & TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCA - (Wm)*(Wn) -> ACCA
  ACCA = ACCA - WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
#  AWB_t = ACCBH;
} 


:msc WmWn_t,ACCA_t^AWB_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x1 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCA - (Wm)*(Wn) -> ACCA
  ACCA = ACCA - WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
  AWB_t = ACCBH;
} 


:msc WmWn_t,ACCA_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x1 &
     TOK_9_6_iiii=0x4 &                    TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCA - (Wm)*(Wn) -> ACCA
  ACCA = ACCA - WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
#  AWB_t = ACCBH;
} 


:msc WmWn_t,ACCA_t^Wy_t^Wyd_t^AWB_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x1 &
     TOK_9_6_iiii=0x4 &  
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCA - (Wm)*(Wn) -> ACCA
  ACCA = ACCA - WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
  AWB_t = ACCBH;
} 


:msc WmWn_t,ACCA_t^Wx_t^Wxd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x1 &
                        TOK_5_2_jjjj=0x4 & TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCA - (Wm)*(Wn) -> ACCA
  ACCA = ACCA - WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
#  AWB_t = ACCBH;
} 


:msc WmWn_t,ACCA_t^Wx_t^Wxd_t^AWB_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x1 &
                        TOK_5_2_jjjj=0x4 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCA - (Wm)*(Wn) -> ACCA
  ACCA = ACCA - WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
  AWB_t = ACCBH;
} 


:msc WmWn_t,ACCA_t^Wx_t^Wxd_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x1 &
                                           TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCA - (Wm)*(Wn) -> ACCA
  ACCA = ACCA - WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
#  AWB_t = ACCBH;
} 


:msc WmWn_t,ACCA_t^Wx_t^Wxd_t^Wy_t^Wyd_t^AWB_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCA_t & OP_14=0x1 &
     
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCA - (Wm)*(Wn) -> ACCA
  ACCA = ACCA - WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCB rounded -> AWB
  AWB_t = ACCBH;
} 


##
##
## ACCB series
##
##

:msc WmWn_t,ACCB_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x1 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 & TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCB - (Wm)*(Wn) -> ACCB
  ACCB = ACCB - WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
#  AWB_t = ACCAH;
} 


:msc WmWn_t,ACCB_t^AWB_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x1 &
     TOK_9_6_iiii=0x4 & TOK_5_2_jjjj=0x4 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCB - (Wm)*(Wn) -> ACCB
  ACCB = ACCB - WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
  AWB_t = ACCAH;
} 


:msc WmWn_t,ACCB_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x1 &
     TOK_9_6_iiii=0x4 &                    TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCB - (Wm)*(Wn) -> ACCB
  ACCB = ACCB - WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
#  AWB_t = ACCAH;
} 


:msc WmWn_t,ACCB_t^Wy_t^Wyd_t^AWB_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x1 &
     TOK_9_6_iiii=0x4 &  
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCB - (Wm)*(Wn) -> ACCB
  ACCB = ACCB - WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
#  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
  AWB_t = ACCAH;
} 


:msc WmWn_t,ACCB_t^Wx_t^Wxd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x1 &
                        TOK_5_2_jjjj=0x4 & TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCB - (Wm)*(Wn) -> ACCB
  ACCB = ACCB - WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
#  AWB_t = ACCAH;
} 


:msc WmWn_t,ACCB_t^Wx_t^Wxd_t^AWB_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x1 &
                        TOK_5_2_jjjj=0x4 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCB - (Wm)*(Wn) -> ACCB
  ACCB = ACCB - WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
#  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
  AWB_t = ACCAH;
} 


:msc WmWn_t,ACCB_t^Wx_t^Wxd_t^Wy_t^Wyd_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x1 &
                                           TOK_1_0_aa=0x2 & 
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCB - (Wm)*(Wn) -> ACCB
  ACCB = ACCB - WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
#  AWB_t = ACCAH;
} 


:msc WmWn_t,ACCB_t^Wx_t^Wxd_t^Wy_t^Wyd_t^AWB_t is 
     OP_23_20=0xC & OP_19=0x0 & WmWn_t & ACCB_t & OP_14=0x1 &
     
     Wxd_t & Wyd_t & Wx_t & Wy_t & AWB_t {

# Note: MAC-class instruction

  # ACCB - (Wm)*(Wn) -> ACCB
  ACCB = ACCB - WmWn_t;
  testSRH_OA();
  testSRH_SA();

  # ([Wx]) -> Wxd
  # (Wx) +/- kx -> Wx
  Wxd_t = Wx_t;

  # ([Wy]) -> Wyd
  # (Wy) +/- ky -> Wy
  Wyd_t = Wy_t;

  # ACCA rounded -> AWB
  AWB_t = ACCAH;
} 
@endif


:mul.w f13_t is OP_23_16=0xbc & OP_15=0 & OP_13=0x0 & OP_14=0 & f13_t  { 

  W3W2 = zext(f13_t) * zext(W0);
}
:mul.b f13byte_t is OP_23_16=0xbc & OP_15=0 & OP_13=0x0 & OP_14=1 & f13byte_t { 

  W2 = zext(f13byte_t) * zext(W0byte);
}


:mul.ss Wbd_t,WsMUL_t,Wndd_t is
  OP_23_20=0xb & OP_19_16=0x9 & OP_15=1 & Wbd_t & Wndd_t & OP_7=0 & $(WSconstraint) & WsMUL_t { 

  Wndd_t = sext(Wbd_t) * sext(WsMUL_t);
}


@if defined(dsPIC33E) || defined(dsPIC33C)
A7_t:      ACCA                             is TOK_7=0 & ACCA
  { export ACCA; }

A7_t:      ACCB                             is TOK_7=1 & ACCB
  { export ACCB; }

:mul.ss Wbd_t,WsMUL_t,A7_t is OP_23_20=0xb & OP_19_16=0x9 & OP_15=1 & Wbd_t & OP_10_8=0x7 & A7_t & $(WSconstraint) & WsMUL_t { 

  A7_t = sext(Wbd_t) * sext(WsMUL_t);
}
@endif


:mul.su Wbd_t,k5,Wndd_t is OP_23_20=0xb & OP_19_16=0x9 & OP_15=0 & Wbd_t & Wndd_t & OP_7=0 & OP_6_5=3 & k5 { 

  Wndd_t = sext(Wbd_t) * zext(k5);
}

:mul.su Wbd_t,WsMUL_t,Wndd_t is OP_23_20=0xb & OP_19_16=0x9 & OP_15=0 & Wbd_t & Wndd_t & OP_7=0 & $(WSconstraint) & WsMUL_t { 

  Wndd_t = sext(Wbd_t) * zext(WsMUL_t);
}


@if defined(dsPIC33E) || defined(dsPIC33C)
:mul.su Wbd_t,WsMUL_t,A7_t is
  OP_23_20=0xb & OP_19_16=0x9 & OP_15=0 & Wbd_t & OP_10_8=0x7 & A7_t & $(WSconstraint) & WsMUL_t { 

  A7_t = sext(Wbd_t) * zext(WsMUL_t);
}


:mul.su Wbd_t,k5,A7_t is
  OP_23_20=0xb & OP_19_16=0x9 & OP_15=0 & Wbd_t & OP_10_8=0x7 & A7_t & OP_6_5=0x3 & k5 {
 
  A7_t = sext(Wbd_t) * zext(k5); 
}
@endif


:mul.us Wbd_t,WsMUL_t,Wndd_t  is
  OP_23_20=0xb & OP_19_16=0x8 & OP_15=1 & Wbd_t & Wndd_t & OP_7=0 & $(WSconstraint) & WsMUL_t { 

  Wndd_t = zext(Wbd_t) * sext(WsMUL_t);
}


@if defined(dsPIC33E) || defined(dsPIC33C)
:mul.us Wbd_t,WsMUL_t,A7_t is
  OP_23_20=0xb & OP_19_16=0x8 & OP_15=1 & Wbd_t & OP_10_8=0x7 & A7_t & $(WSconstraint) & WsMUL_t { 

  A7_t = zext(Wbd_t) * sext(WsMUL_t);
}
@endif


:mul.uu Wbd_t,k5,Wndd_t is
  OP_23_20=0xb & OP_19_16=0x8 & OP_15=0 & Wbd_t & Wndd_t & OP_7=0 & OP_6_5=0x3 & k5  { 

  Wndd_t = zext(Wbd_t) * zext(k5);
}

:mul.uu Wbd_t,WsMUL_t,Wndd_t is OP_23_20=0xb & OP_19_16=0x8 & OP_15=0 & Wbd_t & Wndd_t & OP_7=0 & $(WSconstraint) & WsMUL_t { 

  Wndd_t = zext(Wbd_t) * zext(WsMUL_t);
}


@if defined(dsPIC33E) || defined(dsPIC33C)
:mul.uu Wbd_t,WsMUL_t,A7_t is
  OP_23_20=0xb & OP_19_16=0x8 & OP_15=0 & Wbd_t & OP_10_8=0x7 & A7_t & $(WSconstraint) & WsMUL_t { 

  A7_t = zext(Wbd_t) * zext(WsMUL_t);
}


:mul.uu Wbd_t,k5,A7_t is
  OP_23_20=0xb & OP_19_16=0x8 & OP_15=0 & Wbd_t & OP_10_8=0x7 & A7_t & OP_6_5=0x3 & k5 { 

  A7_t = zext(Wbd_t) * zext(k5);
}
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:mulw.ss Wbd_t,WsMUL_t,Wndd_t is
  OP_23_20=0xb & OP_19_16=0x9 & OP_15=1 & Wbd_t & Wndd_t & OP_7=1 & $(WSconstraint) & WsMUL_t { 

  Wndd_t = sext(Wbd_t) * sext(WsMUL_t);
}
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:mulw.su Wbd_t,WsMUL_t,Wndd_t is
  OP_23_20=0xb & OP_19_16=0x9 & OP_15=0 & Wbd_t & Wndd_t & OP_7=1 & $(WSconstraint) & WsMUL_t { 

  Wndd_t = sext(Wbd_t) * zext(WsMUL_t);
}


:mulw.su Wbd_t,k5_t,Wndd_t is
  OP_23_20=0xb & OP_19_16=0x9 & OP_15=0 & Wbd_t & Wndd_t & OP_7=1 & OP_6_5=3 & k5_t { 

  Wndd_t = sext(Wbd_t) * zext(k5_t);
}
@endif

@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)

:mulw.us Wbd_t,WsMUL_t,Wndd_t is
  OP_23_20=0xb & OP_19_16=0x8 & OP_15=1 & Wbd_t & Wndd_t & OP_7=1 & $(WSconstraint) & WsMUL_t { 

  Wndd_t = zext(Wbd_t) * sext(WsMUL_t);
}
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:mulw.uu Wbd_t,WsMUL_t,Wndd_t is
  OP_23_20=0xb & OP_19_16=0x8 & OP_15=0 & Wbd_t & Wndd_t & OP_7=1 & $(WSconstraint) & WsMUL_t { 

  Wndd_t = zext(Wbd_t) * zext(WsMUL_t);
}


:mulw.uu Wbd_t,k5_t,Wndd_t is
  OP_23_20=0xb & OP_19_16=0x8 & OP_15=0 & Wbd_t & Wndd_t & OP_7=1 & OP_6_5=3 & k5_t { 

  Wndd_t = zext(Wbd_t) * zext(k5_t);
}
@endif


:neg.w f13_t^WREG_t         is OP_23_16=0xee & OP_15=0  & OP_14=0 & WREG_t & f13_t  { 

    WREG_t = -f13_t;

    SRH_DC = 0;
    SRL_OV = 0;
    SRL_C  = 0;
    testSRL_N(WREG_t);
    testSRL_Z(WREG_t);
}

:neg.b f13byte_t^WREGbyte_t is OP_23_16=0xee & OP_15=0  & OP_14=1 & WREGbyte_t & f13byte_t  { 

    WREGbyte_t = -f13byte_t;

    SRH_DC = 0;
    SRL_OV = 0;
    SRL_C  = 0;
    testSRL_N(WREGbyte_t);
    testSRL_Z(WREGbyte_t);	
}


:neg.w Ws_t,Wd_t is OP_23_16=0xea & OP_15=0 & OP_14=0 & $(WDconstraint) & Wd_t & $(WSconstraint) & Ws_t { 

    local result = -Ws_t;
    build Wd_t;
    Wd_t = result;
    
    SRH_DC = 0;
    SRL_OV = 0;
    SRL_C  = 0;
    testSRL_N(result);
    testSRL_Z(result);
}

:neg.b Wsbyte_t,Wdbyte_t is OP_23_16=0xea & OP_15=0 & OP_14=1 & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & Wsbyte_t { 

    local result = -Wsbyte_t;
    build Wdbyte_t;
    Wdbyte_t = result;
    
    SRH_DC = 0;
    SRL_OV = 0;
    SRL_C  = 0;
    testSRL_N(result);
    testSRL_Z(result);
}


@if defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) || defined(dsPIC33C)
:neg ACCA_t is OP_23_20=0xC & OP_19_16=0xB & ACCA_t &
     OP_14_12=0x1 & OP_11_8=0x0 & OP_7_4=0x0 & OP_3_0=0x0 {

  ACCA = -ACCA;
  testSRH_OA();
  testSRH_SA();
} 

:neg ACCB_t is OP_23_20=0xC & OP_19_16=0xB & ACCB_t &
     OP_14_12=0x1 & OP_11_8=0x0 & OP_7_4=0x0 & OP_3_0=0x0 {

  ACCB = -ACCB;
  testSRH_OB();
  testSRH_SB();
} 
@endif


:nop is OP_23_16=0x0 { 
  # No definition on purpose 
}


#
:nopr is OP_23_16=0xff {
  # No definition on purpose 
}


:pop f15_t is OP_23_20=0xF & OP_19_16=0x9 & f15_t & OP_0=0x0 {

  W15 	= W15 - 2;
  f15_t = *[ram]:2 W15;
}


:pop movWd is OP_23_20=0x7 & OP_19=0x1 & movWd & OP_14=0x0 & OP_6_4=0x4 & OP_3_0=0xF {

  W15 	= W15 - 2;
  local result = *[ram]:2 W15;
  build movWd;
  movWd = result;
}


:pop.d Wndd_t is OP_23_20=0xB & OP_19_16=0xE & OP_15_12=0x0 & OP_11=0x0 & Wndd_t & OP_7_4=0x4 & OP_3_0=0xF {

  W15 = W15 - 4;
  Wndd_t = *[ram]:4 W15;
}


:pop.s is OP_23_20=0xF & OP_19_16=0xE & OP_15_12=0x8 & OP_11_8=0x0 & OP_7_4=0x0 & OP_3_0=0x0 {

  W0 = SHADOW_W0;
  W1 = SHADOW_W1;
  W2 = SHADOW_W2;
  W3 = SHADOW_W3;

  SRL_C  = SHADOW_SRL_C;
  SRL_Z  = SHADOW_SRL_Z;
  SRL_OV = SHADOW_SRL_OV;
  SRL_N  = SHADOW_SRL_N;
  SRH_DC = SHADOW_SRH_DC;
}


:push f15_t is OP_23_20=0xF & OP_19_16=0x8 & f15_t & OP_0=0x0 {

  *[ram]:2 W15 	= f15_t;
  W15 = W15 + 2;
}


:push movWs is OP_23_20=0x7 & OP_19=0x1 & movWs & OP_14_12=0x1 & OP_11_8=0xF & OP_7=0x1 {

  *[ram]:2 W15 	= movWs;
  W15 = W15 + 2;
}


:push.d TOK_3_1_Dregn is OP_23_20=0xB & OP_19_16=0xE & OP_15_12=0x9 & OP_11_8=0xF & OP_7_4=0x8 & TOK_3_1_Dreg & TOK_3_1_Dregn & OP_0=0x0 {

  *[ram]:4 W15 	= TOK_3_1_Dreg;
  W15 			= W15 + 4;
}


:push.s is OP_23_20=0xF & OP_19_16=0xE & OP_15_12=0xA & OP_11_8=0x0 & OP_7_4=0x0 & OP_3_0=0x0 {

  SHADOW_W0 = W0;
  SHADOW_W1 = W1;
  SHADOW_W2 = W2;
  SHADOW_W3 = W3;

  SHADOW_SRL_C  = SRL_C;
  SHADOW_SRL_Z  = SRL_Z;
  SHADOW_SRL_OV = SRL_OV;
  SHADOW_SRL_N  = SRL_N;
  SHADOW_SRH_DC = SRH_DC;
}


define pcodeop pwrsavOp;

:pwrsav OP_0 is OP_23_1=0x7f2000 & OP_0 { 
	pwrsavOp();
}


@if defined(PIC24F) || defined(PIC24H) || defined(dsPIC30F) || defined(dsPIC33F) 
:rcall  n16_t is OP_23_20=0x0 & OP_19_16=0x7 & n16_t & WordInstNext4 {
  *[ram]:4 W15  = WordInstNext4;
  W15           = W15 + 4;

  call n16_t;
} 
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:rcall  n16_t is OP_23_20=0x0 & OP_19_16=0x7 & n16_t & WordInstNext4 {
  *[ram]:4 W15  = WordInstNext4 | zext(CORCON_SFA);
  W15           = W15 + 4;
  CORCON_SFA    = 0;

  call n16_t;   
} 
@endif


@if defined(PIC24F) || defined(PIC24H) || defined(dsPIC30F) || defined(dsPIC33F) 
:rcall  WnRDest_t is OP_23_20=0x0 & OP_19_16=0x1 & OP_15_12=0x2 & OP_11_8=0x0 & OP_7_4=0x0 & WnRDest_t & WordInstNext4 {
  *[ram]:4 W15  = WordInstNext4;
  W15           = W15 + 4;

  call [WnRDest_t];
} 
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:rcall  WnRDest_t is OP_23_20=0x0 & OP_19_16=0x1 & OP_15_12=0x0 & OP_11_8=0x2 & OP_7_4=0x0 & WnRDest_t & WordInstNext4 {
  *[ram]:4 W15  = WordInstNext4 | zext(CORCON_SFA);
  W15           = W15 + 4;
  CORCON_SFA    = 0;

  call [WnRDest_t];   
} 
@endif


@if defined(PIC24F) || defined(PIC24H) || defined(dsPIC30F) || defined(dsPIC33F) 
:repeat k14_t is OP_23_14=0x24 & k14_t
	[ repeatInstr=1; globalset(inst_next,repeatInstr); ] 
{ 
	RCOUNT     = k14_t + 1;
} 
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:repeat k15_t is OP_23_16=0x09 & OP_15=0 & k15_t
	[ repeatInstr=1; globalset(inst_next,repeatInstr); ] 
{
	RCOUNT     = k15_t + 1;
} 
@endif


@if defined(PIC24F) || defined(PIC24H) || defined(dsPIC30F) || defined(dsPIC33F) 
:repeat TOK_3_0_Wreg is OP_23_4=0x9800 & TOK_3_0_Wreg 
	[ repeatInstr=1; globalset(inst_next,repeatInstr); ] 
{  
	RCOUNT     = TOK_3_0_Wreg & 0x7FFF;
} 
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:repeat TOK_3_0_Wreg is OP_23_4=0x9800 & TOK_3_0_Wreg
	[ repeatInstr=1; globalset(inst_next,repeatInstr); ] 
{ 
	RCOUNT     = TOK_3_0_Wreg;
} 
@endif


:reset is OP_23_0=0xfe0000 {
  SRH_OA 	= 0;
  SRH_OB 	= 0;
  SRH_OAB 	= 0;
  SRH_SA 	= 0;
  SRH_SB 	= 0;
  SRH_SAB 	= 0;
  SRH_DA 	= 0;
  SRH_DC 	= 0;
  SRL_IPL2 	= 0;
  SRL_IPL1 	= 0;
  SRL_IPL0 	= 0;
  SRL_RA 	= 0;
  SRL_N 	= 0;
  SRL_OV 	= 0;
  SRL_Z 	= 0;
  SRL_C 	= 0;
  CORCON_SFA = 0; 
  PC 		= 0;
  goto [PC];
}


@if defined(PIC24F) || defined(PIC24H) || defined(dsPIC30F) || defined(dsPIC33F) 
:retfie is OP_23_20=0x0 & OP_19_16=0x6 & OP_15_12=0x4 & OP_11_8=0x0 & OP_7_4=0x0 & OP_3_0=0x0 {
  W15 	= W15 - 4;
  local tmp 	= *[ram]:4 W15;
  tmpSRL:1 = tmp(3);
  unpackSRL( tmpSRL );
  CORCON_IPL3 = (tmp & 0x00800000) != 0;
  return [tmp & 0x7FFFFF];
}
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:retfie is OP_23_20=0x0 & OP_19_16=0x6 & OP_15_12=0x4 & OP_11_8=0x0 & OP_7_4=0x0 & OP_3_0=0x0 {
  W15 	= W15 - 4;
  local tmp 	= *[ram]:4 W15;
  tmpSRL:1 = tmp(3);
  unpackSRL( tmpSRL );
  CORCON_IPL3 = (tmp & 0x00800000) != 0;
  CORCON_SFA = (tmp & 0x1) != 0;
  return [tmp & 0x7FFFFE];
}
@endif


@if defined(PIC24F) || defined(PIC24H) || defined(dsPIC30F) || defined(dsPIC33F) 
:retlw.w   k10_t,Wn_t is OP_23_20=0x0 & OP_19_16=0x5 & OP_15=0 & k10_t & Wn_t {
  W15 	= W15 - 4;
  local tmp 	= *[ram]:4 W15;
  tmpSRL:1 = tmp(3);
  unpackSRL( tmpSRL );
  CORCON_IPL3 = (tmp & 0x00800000) != 0;
  Wn_t =         k10_t;
  return [tmp & 0x7FFFFF];
} 


:retlw.b   k10byte_t,Wnbyte_t is OP_23_20=0x0 & OP_19_16=0x5 & OP_15=0 & k10byte_t & Wnbyte_t {
  W15 	= W15 - 4;
  local tmp 	= *[ram]:4 W15;
  tmpSRL:1 = tmp(3);
  unpackSRL( tmpSRL );
  CORCON_IPL3 = (tmp & 0x00800000) != 0;
  Wnbyte_t =     k10byte_t;
  return [tmp & 0x7FFFFF];
}
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:retlw.w   k10_t,Wn_t is OP_23_20=0x0 & OP_19_16=0x5 & OP_15=0 & k10_t & Wn_t {
  W15 	= W15 - 4;
  local tmp 	= *[ram]:4 W15;
  tmpSRL:1 = tmp(3);
  unpackSRL( tmpSRL );
  CORCON_IPL3 = (tmp & 0x00800000) != 0;
  CORCON_SFA = (tmp & 0x1) != 0;
  Wn_t = k10_t;
  return [tmp & 0x7FFFFE];
} 


:retlw.b   k10byte_t,Wnbyte_t is OP_23_20=0x0 & OP_19_16=0x5 & OP_15=0 & k10byte_t & Wnbyte_t {
  W15 	= W15 - 4;
  local tmp 	= *[ram]:4 W15;
  tmpSRL:1 = tmp(3);
  unpackSRL( tmpSRL );
  CORCON_IPL3 = (tmp & 0x00800000) != 0;
  CORCON_SFA = 	(tmp & 0x1) != 0;
  Wnbyte_t =     k10byte_t;
  return [tmp & 0x7FFFFE];
}
@endif


@if defined(PIC24F) || defined(PIC24H) || defined(dsPIC30F) || defined(dsPIC33F) 
:return is OP_23_20=0x0 & OP_19_16=0x6 & OP_15_12=0x0 & OP_11_8=0x0 & OP_7_4=0x0 & OP_3_0=0x0 {
  W15 	= W15 - 4;
  local tmp 	= *[ram]:4 W15;
  return [tmp & 0x7FFFFF];
}
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:return is OP_23_20=0x0 & OP_19_16=0x6 & OP_15_12=0x0 & OP_11_8=0x0 & OP_7_4=0x0 & OP_3_0=0x0 {
  W15 	= W15 - 4;
  local tmp 	= *[ram]:4 W15;
  CORCON_SFA = ( tmp & 0x0001 ) != 0;
  tmp = tmp & 0x7FFFFE;
  return [tmp];
}
@endif


:rlc.w f13_t^WREG_t         is OP_23_16=0xd6 & OP_15=1 & WREG_t & f13_t  { 

  local src = f13_t;
  WREG_t = ( src << 1 ) | zext(SRL_C);
  testSRL_N(WREG_t);
  testSRL_Z(WREG_t);
  SRL_C  = ( src & 0x8000 ) != 0; 	
}

:rlc.b f13byte_t^WREGbyte_t is OP_23_16=0xd6 & OP_15=1 & WREGbyte_t & f13byte_t {

  local src = f13byte_t;
  WREGbyte_t = ( src << 1 ) | SRL_C;
  testSRL_N(WREGbyte_t);
  testSRL_Z(WREGbyte_t);
  SRL_C      = ( src & 0x80 ) != 0; 	
}


:rlc.w Ws_t,Wd_t         is OP_23_16=0xd2 & OP_15=1 & TOK_B=0 & $(WDconstraint) & Wd_t & $(WSconstraint) & Ws_t {
 
  local src = Ws_t;
  local result  = (src << 1) | zext(SRL_C);
  build Wd_t;
  Wd_t = result;
  
  testSRL_N(result);
  testSRL_Z(result);
  SRL_C = (src & 0x8000) != 0; 
}


:rlc.b Wsbyte_t,Wdbyte_t is OP_23_16=0xd2 & OP_15=1 & TOK_B=1 & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & Wsbyte_t { 
 
  local src = Wsbyte_t;
  local result  = (src << 1) | SRL_C;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N(result);
  testSRL_Z(result);
  SRL_C     = (src & 0x80) != 0; 
}


:rlnc.w f13_t^WREG_t         is OP_23_16=0xd6 & OP_15=0 & WREG_t & f13_t { 

  local src = f13_t;
  WREG_t  = (src << 1) | ((src & 0x8000) >> 15);
  testSRL_N(WREG_t);
  testSRL_Z(WREG_t);
}
:rlnc.b f13byte_t^WREGbyte_t is OP_23_16=0xd6 & OP_15=0 & WREGbyte_t & f13byte_t  { 

  local src = f13byte_t;
  WREGbyte_t  = (src << 1) | ((src & 0x80) >> 7);
  testSRL_N(WREGbyte_t);
  testSRL_Z(WREGbyte_t);
}


:rlnc.w Ws_t,Wd_t is OP_23_16=0xd2 & OP_15=0 & TOK_B=0 & $(WDconstraint) & Wd_t & $(WSconstraint) & Ws_t {

  local src = Ws_t;
  local result  = (src << 1) | ((src & 0x8000) >> 15);
  build Wd_t;
  Wd_t = result;
  
  testSRL_N(result);
  testSRL_Z(result);
}

:rlnc.b Wsbyte_t,Wdbyte_t is OP_23_16=0xd2 & OP_15=0 & TOK_B=1 & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & Wsbyte_t {

  local src = Wsbyte_t;
  local result  = (src << 1) | ((src & 0x80) >> 7);
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N(result);
  testSRL_Z(result);
}


:rrc.w f13_t^WREG_t         is OP_23_16=0xd7 & OP_15=1 & WREG_t & f13_t { 

  local src = f13_t;
  WREG_t  	= ((zext(SRL_C)) * 0x8000) | (src >> 1);
  testSRL_N(WREG_t);
  testSRL_Z(WREG_t);
  SRL_C 	= (src & 1) != 0; 
}


:rrc.b f13byte_t^WREGbyte_t is OP_23_16=0xd7 & OP_15=1 & WREGbyte_t & f13byte_t {
 
  local src = f13byte_t;
  WREGbyte_t  	= (SRL_C * 0x80) | (src >> 1) ;
  testSRL_N(WREGbyte_t);
  testSRL_Z(WREGbyte_t);
  SRL_C 	= (src & 1) != 0; 
}


:rrc.w Ws_t,Wd_t         is OP_23_16=0xd3 & OP_15=1 & TOK_B=0 & $(WDconstraint) & Wd_t & $(WSconstraint) & Ws_t {

  local src = Ws_t;
  local result  = ((zext(SRL_C)) * 0x8000) | (src >> 1);
  build Wd_t;
  Wd_t = result;
  
  testSRL_N(result);
  testSRL_Z(result);
  SRL_C = (src & 1) != 0; 
}


:rrc.b Wsbyte_t,Wdbyte_t is OP_23_16=0xd3 & OP_15=1 & TOK_B=1 & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & Wsbyte_t { 

  local src = Wsbyte_t;
  local result  = (SRL_C * 0x80) | (src >> 1);
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N(result);
  testSRL_Z(result);
  SRL_C     = (src & 1) != 0; 
}


:rrnc.w f13_t^WREG_t         is OP_23_16=0xd7 & OP_15=0 & TOK_B=0 & WREG_t & f13_t { 

  local src = f13_t;
  WREG_t  = (src >> 1) | ((src & 1) * 0x8000); 
  testSRL_N(WREG_t);
  testSRL_Z(WREG_t);
}


:rrnc.b f13byte_t^WREGbyte_t is OP_23_16=0xd7 & OP_15=0 & TOK_B=1 & WREGbyte_t & f13byte_t  {
 
  local src = f13byte_t;
  WREGbyte_t  = (src >> 1) | ((src & 1) * 0x80); 
  testSRL_N(WREGbyte_t);
  testSRL_Z(WREGbyte_t);
}


:rrnc.w Ws_t,Wd_t         is OP_23_16=0xd3 & OP_15=0 & TOK_B=0 & $(WDconstraint) & Wd_t & $(WSconstraint) & Ws_t {

  local src = Ws_t;
  local result  = (src >> 1) | ((src & 1) * 0x8000); 
  build Wd_t;
  Wd_t = result;
  
  testSRL_N(Wd_t);
  testSRL_Z(Wd_t);
}


:rrnc.b Wsbyte_t,Wdbyte_t is OP_23_16=0xd3 & OP_15=0 & TOK_B=1 & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & Wsbyte_t { 

  local src = Wsbyte_t;
  local result  = (src >> 1) | ((src & 1) * 0x80); 
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N(result);
  testSRL_Z(result);
}


@if defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) || defined(dsPIC33C)
:sac ACCA_t^r4_t,WdWRO_t is OP_23_20=0xC & OP_19_16=0xC & ACCA_t & r4_t & WdWRO_t {

  local tmp:6 	= ACCA s>> (16 + r4_t);
  WdWRO_t 	= tmp:2;
} 

:sac ACCB_t^r4_t,WdWRO_t is OP_23_20=0xC & OP_19_16=0xC & ACCB_t & r4_t & WdWRO_t {

  local tmp:6 	= ACCB s>> (16 + r4_t);
  WdWRO_t 	= tmp:2;
} 
@endif


@if defined(dsPIC33C)
:sac.d ACCA_t^r4_t,Wsnd_t is OP_23_16=0xDC & OP_14=0x0 & OP_7_4=0x0 & ACCA_t & r4_t & Wsnd_t {

  local tmp:6 	= ACCA s>> (16 + r4_t);
  Wsnd_t 	= tmp:2;
} 

:sac.d ACCB_t^r4_t,Wsnd_t is OP_23_16=0xDC & OP_14=0x0 & OP_7_4=0x0 & ACCB_t & r4_t & Wsnd_t {

  local tmp:6 	= ACCB s>> (16 + r4_t);
  Wsnd_t 	= tmp:2;
}
@endif


@if defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) || defined(dsPIC33C)
:sac.r ACCA_t^r4_t,WdWRO_t is OP_23_20=0xC & OP_19_16=0xD & ACCA_t & r4_t & WdWRO_t {

  local tmp:6 	= ( ACCA + (0x80000000 >> (16 - r4_t)) ) s>> (16 + r4_t);
  WdWRO_t 	= tmp:2;
} 

:sac.r ACCB_t^r4_t,WdWRO_t is OP_23_20=0xC & OP_19_16=0xD & ACCB_t & r4_t & WdWRO_t {

  local tmp:6 	= ( ACCB + (0x80000000 >> (16 - r4_t)) ) s>> (16 + r4_t);
  WdWRO_t 	= tmp:2;
} 
@endif


:se Ws_t,Wnd_t is OP_23_11=0x1f60 & Wnd_t & $(WSconstraint) & Ws_t { 

  Wnd_t = sext(Ws_t:1);
  testSRL_N(Wnd_t);
  testSRL_Z(Wnd_t);
  SRL_C = !SRL_N;
}


:setm.w f13_t^WREG_t         is OP_23_16=0xef & OP_15=1 & WREG_t & f13_t {

  WREG_t = 0xFFFF; 
}

:setm.b f13byte_t^WREGbyte_t is OP_23_16=0xef & OP_15=1 & WREGbyte_t & f13byte_t {

  WREGbyte_t = 0xFF; 
}


:setm.w Wd_t     is OP_23_16=0xeb & OP_15=1 & OP_6_0=0x0 & TOK_B=0 & $(WDconstraint) & Wd_t {
 
  Wd_t = 0xFFFF;
}


:setm.b Wdbyte_t is OP_23_16=0xeb & OP_15=1 & OP_6_0=0x0 & TOK_B=1 & $(WDconstraint) & Wdbyte_t { 

  Wdbyte_t = 0xFF;
}


@if defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) || defined(dsPIC33C)
:sftac ACCA_t,k6_t is
     OP_23_20=0xC & OP_19_16=0x8 & ACCA_t & OP_14_12=0x0 & OP_11_8=0x0 & OP_7_6=0x1 & k6_t {

  local tmp:8 = (sext(ACCA) << (16 - k6_t)) >> 16;
  ACCA 	= tmp:6;
  testSRH_OA();
  testSRH_SA();
} 

:sftac ACCB_t,k6_t is
     OP_23_20=0xC & OP_19_16=0x8 & ACCB_t & OP_14_12=0x0 & OP_11_8=0x0 & OP_7_6=0x1 & k6_t {

  local tmp:8 = (sext(ACCB) << (16 - k6_t)) >> 16;
  ACCB 	= tmp:6;
  testSRH_OB();
  testSRH_SB();
} 
@endif


@if defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) || defined(dsPIC33C)
:sftac ACCA_t,Wbsft_t is
     OP_23_20=0xC & OP_19_16=0x8 & ACCA_t & OP_14_12=0x0 & OP_11_8=0x0 & OP_7_4=0x0 & Wbsft_t {

  local tmp:8 = (sext(ACCA) << (16 - Wbsft_t)) >> 16;
  ACCA 	= tmp:6;
  testSRH_OA();
  testSRH_SA();
} 

:sftac ACCB_t,Wbsft_t is
     OP_23_20=0xC & OP_19_16=0x8 & ACCB_t & OP_14_12=0x0 & OP_11_8=0x0 & OP_7_4=0x0 & Wbsft_t {

  local tmp:8 = (sext(ACCB) << (16 - Wbsft_t)) >> 16;
  ACCB 	= tmp:6;
  testSRH_OB();
  testSRH_SB();
} 
@endif


:sl.w f13_t^WREG_t is OP_23_20=0xD & OP_19_16=0x4 & OP_15=0x0 & WREG_t & f13_t { 

  local src = f13_t;
  WREG_t = src << 1;
  testSRL_N(WREG_t);
  testSRL_Z(WREG_t);
  SRL_C  = ((src & 0x8000) != 0);
}


:sl.b f13byte_t^WREGbyte_t is OP_23_20=0xD & OP_19_16=0x4 & OP_15=0x0 & WREGbyte_t & f13byte_t  { 

  local src = f13byte_t;
  WREGbyte_t = src << 1;
  testSRL_N(WREGbyte_t);
  testSRL_Z(WREGbyte_t);
  SRL_C = ((src & 0x80) != 0);
}


:sl.w Ws_t,Wd_t is OP_23_20=0xD & OP_19_16=0x0 & OP_15=0x0 & TOK_B=0 & $(WDconstraint) & Wd_t & $(WSconstraint) & Ws_t { 

  local src = Ws_t;
  local result 	=  src << 1;
  build Wd_t;
  Wd_t = result;
  
  testSRL_N(result);
  testSRL_Z(result);
  SRL_C = ((src & 0x8000) != 0);
}

:sl.b Wsbyte_t,Wdbyte_t is OP_23_20=0xD & OP_19_16=0x0 & OP_15=0x0 & TOK_B=1 & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & Wsbyte_t {

  local src = Wsbyte_t;
  local result = src << 1;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N(result);
  testSRL_Z(result);
  SRL_C = ((src & 0x80) != 0);
}


:sl Wbd_t,k4_t,Wnd_t is OP_23_20=0xD & OP_19_16=0xD & OP_15=0x0 & Wbd_t & Wnd_t & OP_6_4=0x4 & k4_t {
 
  Wnd_t =  Wbd_t << k4_t;
  testSRL_N(Wnd_t);
  testSRL_Z(Wnd_t);
}


:sl Wbd_t,Wns_t,Wnd_t is OP_23_20=0xD & OP_19_16=0xD & OP_15=0x0 & Wbd_t & Wnd_t & OP_6_4=0x0 & Wns_t { 

  Wnd_t =  Wbd_t << (Wns_t & 0x1F);
  testSRL_N(Wnd_t);
  testSRL_Z(Wnd_t);
}

# SSTEP - ICD instruction compatible with Microchips ICD debugging hardware
# TODO: locate encoding details for SSTEP instruction 
# define pcodeop sstep;
# :sstep is OP_23_0=?? {
#	sstep(); # In-Circuit Debugger (ICD) Single Step
# }

:sub.w   f13_t^WREG_t is OP_23_20=0xB & OP_19_16=0x5 & OP_15=0 & WREG_t & f13_t {

  local src = f13_t;
  subflags( src,  W0 );

  WREG_t =       src - W0;

  testSRL_N     ( WREG_t );
  testSRL_Z     ( WREG_t );
  testSRH_DCword( WREG_t );
}


:sub.b f13byte_t^WREGbyte_t is OP_23_20=0xB & OP_19_16=0x5 & OP_15=0 & WREGbyte_t & f13byte_t {

  local src = f13byte_t;
  subflags( src,  W0byte );

  WREGbyte_t =   src - W0byte;

  testSRL_N     ( WREGbyte_t );
  testSRL_Z     ( WREGbyte_t );
  testSRH_DCbyte( WREGbyte_t );
}


:sub.w   k10_t,Wn_t is OP_23_20=0xB & OP_19_16=0x1 & OP_15=0 & k10_t & Wn_t {

  subflags( Wn_t,  k10_t );

  Wn_t =         Wn_t - k10_t;

  testSRL_N     ( Wn_t );
  testSRL_Z     ( Wn_t );
  testSRH_DCword( Wn_t );
} 


:sub.b   k10byte_t,Wnbyte_t is OP_23_20=0xB & OP_19_16=0x1 & OP_15=0 & k10byte_t & Wnbyte_t {

  subflags( Wnbyte_t,  k10byte_t );

  Wnbyte_t =     Wnbyte_t - k10byte_t;

  testSRL_N     ( Wnbyte_t );
  testSRL_Z     ( Wnbyte_t );
  testSRH_DCbyte( Wnbyte_t );
}


:sub.w   Wb_t,k5_t,Wd_t is OP_23_20=0x5 & OP_19=0x0 & OP_6_5=0x3 & Wb_t & $(WDconstraint) & Wd_t & k5_t {

  subflags( Wb_t,  k5_t );

  local result = Wb_t - k5_t;
  build Wd_t;
  Wd_t = result;

  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCword( result );
} 


:sub.b  Wbbyte_t,k5byte_t,Wdbyte_t is
        OP_23_20=0x5 & OP_19=0x0 & OP_6_5=0x3 & Wbbyte_t & $(WDconstraint) & Wdbyte_t & k5byte_t {

  subflags( Wbbyte_t,  k5byte_t );

  local result =   Wbbyte_t - k5byte_t;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCbyte( result );
} 


:sub.w   Wb_t,Ws_t,Wd_t is OP_23_20=0x5 & OP_19=0x0 & TOK_B=0 & Wb_t & $(WDconstraint) & Wd_t & $(WSconstraint) & Ws_t {

  local src = Ws_t; 
  subflags( Wb_t,  src );

  local result =  Wb_t - src;
  build Wd_t;
  Wd_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCword( result );
} 


:sub.b  Wbbyte_t,Wsbyte_t,Wdbyte_t is OP_23_20=0x5 & OP_19=0x0 & TOK_B=1 & Wbbyte_t & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & Wsbyte_t {

  local src = Wsbyte_t;
  subflags( Wbbyte_t,  src );

  local result =     Wbbyte_t - src;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCbyte( result );
} 


@if defined(dsPIC30F) || defined(dsPIC33F) || defined(dsPIC33E) || defined(dsPIC33C)
:sub ACCA_t is
     OP_23_20=0xC & OP_19_16=0xB & ACCA_t & OP_14_12=0x3 & OP_11_8=0x0 & OP_7_4=0x0 & OP_3_0=0x0 {

  ACCA = ACCB - ACCA;
  testSRH_OA();
  testSRH_SA();
} 

:sub ACCB_t is
     OP_23_20=0xC & OP_19_16=0xB & ACCB_t & OP_14_12=0x3 & OP_11_8=0x0 & OP_7_4=0x0 & OP_3_0=0x0 {

  ACCB = ACCA - ACCB;
  testSRH_OB();
  testSRH_SB();
}
@endif


:subb.w   f13_t^WREG_t is OP_23_20=0xB & OP_19_16=0x5 & OP_15=1 & WREG_t & f13_t {

  local notCarry:2 = zext(!SRL_C);
  subflagsWithCarry( f13_t,  W0, notCarry );

  WREG_t =        f13_t - W0 - notCarry;

  testSRL_N      ( WREG_t );
  testSRL_Zsticky( WREG_t );
  testSRH_DCword ( WREG_t );
} 

:subb.b f13byte_t^WREGbyte_t is OP_23_20=0xB & OP_19_16=0x5 & OP_15=1 & WREGbyte_t & f13byte_t {

  local notCarry = !SRL_C;
  subflagsWithCarry( f13byte_t,  W0byte,  notCarry );

  WREGbyte_t =        f13byte_t - W0byte - notCarry;

  testSRL_N      ( WREGbyte_t );
  testSRL_Zsticky( WREGbyte_t );
  testSRH_DCbyte ( WREGbyte_t );
}


:subb.w   k10_t,Wn_t is OP_23_20=0xB & OP_19_16=0x1 & OP_15=1 & k10_t & Wn_t {

  local notCarry:2 = zext(!SRL_C);
  subflagsWithCarry( Wn_t,  k10_t, notCarry );

  Wn_t =          Wn_t - k10_t - notCarry;

  testSRL_N      ( Wn_t );
  testSRL_Zsticky( Wn_t );
  testSRH_DCword ( Wn_t );
} 


:subb.b   k10byte_t,Wnbyte_t is OP_23_20=0xB & OP_19_16=0x1 & OP_15=1 & k10byte_t & Wnbyte_t {

  local notCarry = !SRL_C;
  subflagsWithCarry( Wnbyte_t,  k10byte_t,  notCarry );

  Wnbyte_t =          Wnbyte_t - k10byte_t - notCarry;

  testSRL_N      ( Wnbyte_t );
  testSRL_Zsticky( Wnbyte_t );
  testSRH_DCbyte ( Wnbyte_t );
}


:subb.w   Wb_t,k5_t,Wd_t is OP_23_20=0x5 & OP_19=0x1 & OP_6_5=0x3 & Wb_t & $(WDconstraint) & Wd_t & k5_t {

  local notCarry:2 = zext(!SRL_C);
  subflagsWithCarry( Wb_t,  k5_t, notCarry );

  local result = Wb_t - k5_t - notCarry;
  build Wd_t;
  Wd_t = result;
  
  testSRL_N      ( result );
  testSRL_Zsticky( result );
  testSRH_DCword ( result );
} 

:subb.b  Wbbyte_t,k5byte_t,Wdbyte_t is
         OP_23_20=0x5 & OP_19=0x1 & OP_6_5=0x3 & Wbbyte_t & $(WDconstraint) & Wdbyte_t & k5byte_t {

  local notCarry = !SRL_C;
  subflagsWithCarry( Wbbyte_t,  k5byte_t,  notCarry );

  local result =   Wbbyte_t - k5byte_t - notCarry;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N      ( result );
  testSRL_Zsticky( result );
  testSRH_DCbyte ( result );
} 


:subb.w   Wb_t,Ws_t,Wd_t is OP_23_20=0x5 & OP_19=0x1 & TOK_B=0 & Wb_t & $(WDconstraint) & Wd_t & $(WSconstraint) & Ws_t {

  local notCarry:2 = zext(!SRL_C);
  local src = Ws_t;
  subflagsWithCarry( Wb_t,  src, notCarry );

  local result =    Wb_t - src - notCarry;
  build Wd_t;
  Wd_t = result;
  
  testSRL_N      ( result );
  testSRL_Zsticky( result );
  testSRH_DCword ( result );
} 


:subb.b  Wbbyte_t,Wsbyte_t,Wdbyte_t is OP_23_20=0x5 & OP_19=0x1 & TOK_B=1 & Wbbyte_t & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & Wsbyte_t {

  local notCarry = !SRL_C;
  local src = Wsbyte_t;
  subflagsWithCarry( Wbbyte_t,  src,  notCarry );

  local result =          Wbbyte_t - src - notCarry;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N      ( result );
  testSRL_Zsticky( result );
  testSRH_DCbyte ( result );
} 


:subbr.w   f13_t^WREG_t is OP_23_20=0xB & OP_19_16=0xD & OP_15=1 & WREG_t & f13_t {

  local notCarry:2 = zext(!SRL_C);
  local src = f13_t;
  subflagsWithCarry( W0,  src, notCarry );

  WREG_t =        W0 - src - notCarry;

  testSRL_N      ( WREG_t );
  testSRL_Zsticky( WREG_t );
  testSRH_DCword ( WREG_t );
} 

:subbr.b f13byte_t^WREGbyte_t is OP_23_20=0xB & OP_19_16=0xD & OP_15=1 & WREGbyte_t & f13byte_t {

  local notCarry = !SRL_C;
  local src = f13byte_t;
  subflagsWithCarry( W0byte,  src,  notCarry );

  WREGbyte_t =        W0byte - src - notCarry;

  testSRL_N      ( WREGbyte_t );
  testSRL_Zsticky( WREGbyte_t );
  testSRH_DCbyte ( WREGbyte_t );
}


:subbr.w   Wb_t,k5_t,Wd_t is OP_23_20=0x1 & OP_19=0x1 & OP_6_5=0x3 & Wb_t & $(WDconstraint) & Wd_t & k5_t {

  local notCarry:2 = zext(!SRL_C);
  subflagsWithCarry( k5_t,  Wb_t,  notCarry );

  local result =  k5_t - Wb_t - notCarry;
  build Wd_t;
  Wd_t = result;
  
  testSRL_N      ( result );
  testSRL_Zsticky( result );
  testSRH_DCword ( result );
} 


:subbr.b  Wbbyte_t,k5byte_t,Wdbyte_t is
         OP_23_20=0x1 & OP_19=0x1 & OP_6_5=0x3 & Wbbyte_t & $(WDconstraint) & Wdbyte_t & k5byte_t {

  local notCarry = !SRL_C;
  subflagsWithCarry( k5byte_t,  Wbbyte_t,  notCarry );

  local result =          k5byte_t - Wbbyte_t - notCarry;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N      ( result );
  testSRL_Zsticky( result );
  testSRH_DCbyte ( result );
} 


:subbr.w   Wb_t,Ws_t,Wd_t is OP_23_20=0x1 & OP_19=0x1 & TOK_B=0 & Wb_t & $(WDconstraint) & Wd_t & $(WSconstraint) & Ws_t {

  local notCarry:2 = zext(!SRL_C);
  local src = Ws_t;
  subflagsWithCarry( src,  Wb_t,  notCarry );

  local result =   src - Wb_t - notCarry;
  build Wd_t;
  Wd_t = result;
  
  testSRL_N      ( result );
  testSRL_Zsticky( result );
  testSRH_DCword ( result );
} 


:subbr.b  Wbbyte_t,Wsbyte_t,Wdbyte_t is OP_23_20=0x1 & OP_19=0x1 & TOK_B=1 & Wbbyte_t & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & Wsbyte_t {

  local notCarry = !SRL_C;
  local src = Wsbyte_t;
  subflagsWithCarry( src,  Wbbyte_t,  notCarry );

  local result =          src - Wbbyte_t - notCarry;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N      ( result );
  testSRL_Zsticky( result );
  testSRH_DCbyte ( result );
} 


:subr.w   f13_t^WREG_t is OP_23_20=0xB & OP_19_16=0xD & OP_15=0 & WREG_t & f13_t {

  local src = f13_t;
  subflags( W0,  src );

  WREG_t =       W0 - src;

  testSRL_N     ( WREG_t );
  testSRL_Z     ( WREG_t );
  testSRH_DCword( WREG_t );
}


:subr.b f13byte_t^WREGbyte_t is OP_23_20=0xB & OP_19_16=0xD & OP_15=0 & WREGbyte_t & f13byte_t {

  local src = f13byte_t;
  subflags( W0byte,  src );

  WREGbyte_t =   W0byte - src;

  testSRL_N     ( WREGbyte_t );
  testSRL_Z     ( WREGbyte_t );
  testSRH_DCbyte( WREGbyte_t );
}


:subr.w   Wb_t,k5_t,Wd_t is OP_23_20=0x1 & OP_19=0x0 & OP_6_5=0x3 & Wb_t & $(WDconstraint) & Wd_t & k5_t {

  subflags( k5_t,  Wb_t );

  local result =   k5_t - Wb_t;
  build Wd_t;
  Wd_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCword( result );
} 


:subr.b  Wbbyte_t,k5byte_t,Wdbyte_t is
        OP_23_20=0x1 & OP_19=0x0 & OP_6_5=0x3 & Wbbyte_t & $(WDconstraint) & Wdbyte_t & k5byte_t {

  subflags( k5byte_t,  Wbbyte_t );

  local result =     k5byte_t - Wbbyte_t;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCbyte( result );
} 


:subr.w   Wb_t,Ws_t,Wd_t is OP_23_20=0x1 & OP_19=0x0 & TOK_B=0 & Wb_t & $(WDconstraint) & Wd_t & $(WSconstraint) & Ws_t {

  local src = Ws_t;
  subflags( src,  Wb_t );

  local result =         src - Wb_t;
  build Wd_t;
  Wd_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCword( result );
} 


:subr.b  Wbbyte_t,Wsbyte_t,Wdbyte_t is OP_23_20=0x1 & OP_19=0x0 & TOK_B=1 & Wbbyte_t & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & Wsbyte_t {

  local src = Wsbyte_t;
  subflags( src,  Wbbyte_t );

  local result =     src - Wbbyte_t;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N     ( result );
  testSRL_Z     ( result );
  testSRH_DCbyte( result );
} 


:swap.w Wn_t is OP_23_20=0xF & OP_19_16=0xD & OP_15=1 & OP_13_4=0x0 & TOK_B=0 & Wn_t {

  Wn_t = ((Wn_t & 0xFF) << 8) | ((Wn_t & 0xFF00) >> 8);
}


:swap.b Wnbyte_t is OP_23_20=0xF & OP_19_16=0xD & OP_15=1 & OP_13_4=0x0 & TOK_B=1 & Wnbyte_t {

  Wnbyte_t = ((Wnbyte_t & 0xF) << 4) | ((Wnbyte_t & 0xF0) >> 4); 
}


# constructor  Encoding: 1011 1010 1Bqq qddd dppp ssss 
:tblrdh.w WsROM_t,Wd_t         is OP_23_20=0xB & OP_19_16=0xA & OP_15=1 & TOK_B=0 & $(WDconstraint) & Wd_t & $(WSconstraint) & WsROM_t {
 
  local src = WsROM_t;
  local result	= zext( *[rom]:1 (src | 1) );
  build Wd_t;
  Wd_t = result;
}

:tblrdh.b WsROM_t,Wdbyte_t is OP_23_20=0xB & OP_19_16=0xA & OP_15=1 & TOK_B=1 & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & WsROM_t { 

  local src = WsROM_t;
  local result:1 = 0;
  
  if ( (src & 0x1) != 0) goto <done>;
    result = *[rom]:1 (src | 1);
    
<done>
  build Wdbyte_t;
  Wdbyte_t = result;
}


# constructor  Encoding: 1011 1010 0Bqq qddd dppp ssss 
:tblrdl.w WsROM_t,Wd_t         is OP_23_20=0xB & OP_19_16=0xA & OP_15=0 & TOK_B=0 & $(WDconstraint) & Wd_t & $(WSconstraint) & WsROM_t { 
  local src = WsROM_t;
  local result	= *[rom]:2 (src & 0xfffffe);
  build Wd_t;
  Wd_t = result;
}

:tblrdl.b WsROM_t,Wdbyte_t is OP_23_20=0xB & OP_19_16=0xA & OP_15=0 & TOK_B=1 & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & WsROM_t { 
  local src = WsROM_t;
  local lbit = src & 1;
  local val = *[rom]:2 (src & 0xfffffe);
  if (lbit == 0) goto <noalign>;
  val = val >> 8;
 <noalign>
  local result = val:1;
  build Wdbyte_t;
  Wdbyte_t = result;
}


:tblwth.w Ws_t,WdROM_t         is OP_23_20=0xB & OP_19_16=0xB & OP_15=1 & TOK_B=0 & $(WDconstraint) & WdROM_t & $(WSconstraint) & Ws_t {
 
  local src = Ws_t;
  local addr = WdROM_t | 1;  # add 1, should be word alligned
  # writing to upper byte PM<23:16>, can't write to padding byte
  *[rom]:1 addr = src;
}

:tblwth.b Wsbyte_t,WdROM_t is OP_23_20=0xB & OP_19_16=0xB & OP_15=1 & TOK_B=1 & $(WDconstraint) & WdROM_t & $(WSconstraint) & Wsbyte_t { 

  local src = Wsbyte_t;
  local addr = WdROM_t;
  local lbit = addr & 1;
  
  if ( lbit != 0) goto <done>;
    addr = addr | 1;
    *[rom]:1 addr = src;

  <done>
}


:tblwtl.w Ws_t,WdROM_t         is OP_23_20=0xB & OP_19_16=0xB & OP_15=0 & TOK_B=0 & $(WDconstraint) & WdROM_t & $(WSconstraint) & Ws_t {
 
  local src = Ws_t;
  local addr = WdROM_t & 0xfffffe;
  *[rom]:2 addr = src;
}

:tblwtl.b Wsbyte_t,WdROM_t is OP_23_20=0xB & OP_19_16=0xB & OP_15=0 & TOK_B=1 & $(WDconstraint) & WdROM_t & $(WSconstraint) & Wsbyte_t { 

  local src = zext(Wsbyte_t);
  local addr = WdROM_t;
  local lobit = addr & 1;
  local val = *[rom]:2 addr;
  local mask = 0xff00;
  # if dest is not word aligned, then write to PM<15:7>
  if (lobit == 0) goto <noalign>;
  mask = mask >> 8;  # writing to second byte of word, protect low byte
  src = src << 8;
 <noalign>
  *[rom]:2 addr = (val & mask) | src;
}


@if defined(dsPIC30F) || defined(dsPIC33F) 
define pcodeop Vector;

:trap TOK_n,TOK_k16t is OP_23_20=0 & OP_19_17=5 & TOK_n & TOK_k16t & WordInstNext4 {
  *[ram]:4 W15  = WordInstNext4;
  W15           = W15 + 4;

  *[ram]:2 W15 	= TOK_k16t;
  
  ptr:3 = Vector(TOK_n:1); # uncertain about vector storage
  
  call [ptr];
} 
@endif


@if defined(dsPIC33C)
define pcodeop verifyslave;
:vfslv PSV_t, EDS_t, k13_12_t is OP_23_16=0x03 & OP_15_14=0x2 & OP_11=0 & k13_12_t & EDS_t & PSV_t {
  verifyslave(PSV_t, EDS_t, k13_12_t);
}
@endif


@if defined(PIC24F) || defined(PIC24H) || defined(dsPIC30F) || defined(dsPIC33F) 
:ulnk is OP_23_20=0xF & OP_19_16=0xA & OP_15_12=0x08 & OP_11_8=0x0 & OP_7_4=0x0 & OP_3_0=0x0 {

  W15 = W14;
  W15 = W15 - 2;

  W14 = *[ram]:2 W15;
} 
@endif


@if defined(PIC24E) || defined(dsPIC33E) || defined(dsPIC33C)
:ulnk is OP_23_20=0xF & OP_19_16=0xA & OP_15_12=0x08 & OP_11_8=0x0 & OP_7_4=0x0 & OP_3_0=0x0 {

  W15 	= W14;
  W15 	= W15 - 2;

  W14 	= *[ram]:2 W15;
  CORCON_SFA = 0;
} 
@endif

# URUN - ICD instruction compatible with Microchips ICD debugging hardware
define pcodeop urun;
:urun is OP_23_0=0xDAC000 {
	urun(); # In-Circuit Debugger (ICD) Run
}

:xor.w f13_t^WREG_t is OP_23_20=0xB & OP_19_16=0x6 & OP_15=1 & WREG_t & f13_t  { 

  WREG_t = W0 ^ f13_t; 
  testSRL_N(WREG_t);
  testSRL_Z(WREG_t);
}

:xor.b f13byte_t^WREGbyte_t is OP_23_20=0xB & OP_19_16=0x6 & OP_15=1 & WREGbyte_t & f13byte_t  {

  WREGbyte_t = W0byte ^ f13byte_t;
  testSRL_N(WREGbyte_t);
  testSRL_Z(WREGbyte_t);  
}


:xor.w k10_t,Wn_t is OP_23_20=0xB & OP_19_16=0x2 & OP_15=1 & k10_t & Wn_t {
 
  Wn_t = Wn_t ^ k10_t;
  testSRL_N(Wn_t);
  testSRL_Z(Wn_t);
}

:xor.b k10byte_t,Wnbyte_t is OP_23_20=0xB & OP_19_16=0x2 & OP_15=1 & k10byte_t & Wnbyte_t {

  Wnbyte_t = Wnbyte_t ^ k10byte_t;
  testSRL_N(Wnbyte_t);
  testSRL_Z(Wnbyte_t);
}


:xor.w  Wb_t,k5_t,Wd_t is OP_23_20=0x6 & OP_19=0x1 & Wb_t & $(WDconstraint) & Wd_t & OP_6_5=0x3 & k5_t {
 
  Wd_t = Wb_t ^ k5_t;
  testSRL_N(Wd_t);
  testSRL_Z(Wd_t);
}

:xor.b Wbbyte_t,k5byte_t,Wdbyte_t is OP_23_20=0x6 & OP_19=0x1 & Wbbyte_t & $(WDconstraint) & Wdbyte_t & OP_6_5=0x3 & k5byte_t { 

  Wdbyte_t = Wbbyte_t ^ k5byte_t;
  testSRL_N(Wdbyte_t);
  testSRL_Z(Wdbyte_t);
}


:xor.w Wb_t,Ws_t,Wd_t             is OP_23_20=0x6 & OP_19=0x1 & TOK_B=0 & Wb_t & $(WDconstraint) & Wd_t & $(WSconstraint) & Ws_t {
 
  local result = Wb_t ^ Ws_t;
  build Wd_t;
  Wd_t = result;
  
  testSRL_N(result);
  testSRL_Z(result);
}

:xor.b Wbbyte_t,Wsbyte_t,Wdbyte_t is OP_23_20=0x6 & OP_19=0x1 & TOK_B=1 & Wbbyte_t & $(WDconstraint) & Wdbyte_t & $(WSconstraint) & Wsbyte_t {

  local result = Wbbyte_t ^ Wsbyte_t;
  build Wdbyte_t;
  Wdbyte_t = result;
  
  testSRL_N(result);
  testSRL_Z(result);
}


:ze Ws_t,Wnd_t  is OP_23_20=0xF & OP_19_16=0xB & OP_15_12=0x8 & OP_11=0x0 & Wnd_t & $(WSconstraint) & Ws_t {
 
  local result = zext(Ws_t:1);
  build Wnd_t;
  Wnd_t = result;
  
  SRL_N = 0;
  testSRL_Z(result);
  SRL_C = 1;
}


# UNVERIFIED - not found in manual but was produced by toolchain for PIC30F2010
# There appear to be a few variations of this encoding produced by toolchain 
# but do not decode with objdump
define pcodeop break;
:break   is OP_23_0=0xDA4000 {
	break();
}

} # end with : phase = 2
