Home | History | Annotate | Line # | Download | only in opcodes
msp430-decode.opc revision 1.2.8.1
      1      1.1  christos /* -*- c -*- */
      2  1.2.8.1  pgoyette /* Copyright (C) 2013-2016 Free Software Foundation, Inc.
      3      1.1  christos    Contributed by Red Hat.
      4      1.1  christos    Written by DJ Delorie.
      5      1.1  christos 
      6      1.1  christos    This file is part of the GNU opcodes library.
      7      1.1  christos 
      8      1.1  christos    This library is free software; you can redistribute it and/or modify
      9      1.1  christos    it under the terms of the GNU General Public License as published by
     10      1.1  christos    the Free Software Foundation; either version 3, or (at your option)
     11      1.1  christos    any later version.
     12      1.1  christos 
     13      1.1  christos    It is distributed in the hope that it will be useful, but WITHOUT
     14      1.1  christos    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     15      1.1  christos    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     16      1.1  christos    License for more details.
     17      1.1  christos 
     18      1.1  christos    You should have received a copy of the GNU General Public License
     19      1.1  christos    along with this program; if not, write to the Free Software
     20      1.1  christos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     21      1.1  christos    MA 02110-1301, USA.  */
     22      1.1  christos 
     23      1.1  christos #include "sysdep.h"
     24      1.1  christos #include <stdio.h>
     25      1.1  christos #include <stdlib.h>
     26      1.1  christos #include <string.h>
     27      1.1  christos #include "ansidecl.h"
     28      1.1  christos #include "opcode/msp430-decode.h"
     29      1.1  christos 
     30      1.1  christos static int trace = 0;
     31      1.1  christos 
     32      1.1  christos typedef struct
     33      1.1  christos {
     34      1.1  christos   MSP430_Opcode_Decoded *msp430;
     35      1.1  christos   int (*getbyte)(void *);
     36      1.1  christos   void *ptr;
     37      1.1  christos   unsigned char *op;
     38      1.1  christos   int op_ptr;
     39      1.1  christos   int pc;
     40      1.1  christos } LocalData;
     41      1.1  christos 
     42      1.1  christos #define AU ATTRIBUTE_UNUSED
     43      1.1  christos #define GETBYTE() getbyte_swapped (ld)
     44      1.1  christos #define B ((unsigned long) GETBYTE ())
     45      1.1  christos 
     46      1.1  christos static int
     47      1.1  christos getbyte_swapped (LocalData *ld)
     48      1.1  christos {
     49      1.1  christos   int b;
     50      1.1  christos 
     51      1.1  christos   if (ld->op_ptr == ld->msp430->n_bytes)
     52      1.1  christos     {
     53      1.1  christos       do
     54      1.1  christos 	{
     55      1.1  christos 	  b = ld->getbyte (ld->ptr);
     56      1.1  christos 	  ld->op [(ld->msp430->n_bytes++)^1] = b;
     57      1.1  christos 	}
     58      1.1  christos       while (ld->msp430->n_bytes & 1);
     59      1.1  christos     }
     60      1.1  christos   return ld->op[ld->op_ptr++];
     61      1.1  christos }
     62      1.1  christos 
     63      1.1  christos #define ID(x)		msp430->id = x
     64      1.1  christos 
     65      1.1  christos #define OP(n, t, r, a) (msp430->op[n].type = t,	     \
     66      1.1  christos 		        msp430->op[n].reg = r,	     \
     67      1.1  christos 		        msp430->op[n].addend = a)
     68      1.1  christos 
     69      1.1  christos #define OPX(n, t, r1, r2, a)	 \
     70      1.1  christos   (msp430->op[n].type = t,	 \
     71      1.1  christos    msp430->op[n].reg = r1,	 \
     72      1.1  christos    msp430->op[n].reg2 = r2,	 \
     73      1.1  christos    msp430->op[n].addend = a)
     74      1.1  christos 
     75      1.1  christos #define SYNTAX(x)	msp430->syntax = x
     76      1.1  christos #define UNSUPPORTED()	msp430->syntax = "*unknown*"
     77      1.1  christos 
     78      1.1  christos #define DC(c)		OP (0, MSP430_Operand_Immediate, 0, c)
     79      1.1  christos #define DR(r)		OP (0, MSP430_Operand_Register, r, 0)
     80      1.1  christos #define DM(r, a)	OP (0, MSP430_Operand_Indirect, r, a)
     81      1.1  christos #define DA(a)		OP (0, MSP430_Operand_Indirect, MSR_None, a)
     82      1.1  christos #define AD(r, ad)	encode_ad (r, ad, ld, 0)
     83      1.1  christos #define ADX(r, ad, x)	encode_ad (r, ad, ld, x)
     84      1.1  christos 
     85      1.1  christos #define SC(c)		OP (1, MSP430_Operand_Immediate, 0, c)
     86      1.1  christos #define SR(r)		OP (1, MSP430_Operand_Register, r, 0)
     87      1.1  christos #define SM(r, a)	OP (1, MSP430_Operand_Indirect, r, a)
     88      1.1  christos #define SA(a)		OP (1, MSP430_Operand_Indirect, MSR_None, a)
     89      1.1  christos #define SI(r)		OP (1, MSP430_Operand_Indirect_Postinc, r, 0)
     90      1.1  christos #define AS(r, as)	encode_as (r, as, ld, 0)
     91      1.1  christos #define ASX(r, as, x)	encode_as (r, as, ld, x)
     92      1.1  christos 
     93      1.1  christos #define BW(x)		msp430->size = (x ? 8 : 16)
     94      1.1  christos /* The last 20 is for SWPBX.Z and SXTX.A.  */
     95      1.1  christos #define ABW(a,x)	msp430->size = (a ? ((x ? 8 : 16)) : (x ? 20 : 20))
     96      1.1  christos 
     97      1.1  christos #define IMMU(bytes)	immediate (bytes, 0, ld)
     98      1.1  christos #define IMMS(bytes)	immediate (bytes, 1, ld)
     99      1.1  christos 
    100      1.1  christos /* Helper macros for known status bits settings.  */
    101      1.1  christos #define	F_____		msp430->flags_1 = msp430->flags_0 = 0; msp430->flags_set = 0
    102      1.1  christos #define	F_VNZC		msp430->flags_1 = msp430->flags_0 = 0; msp430->flags_set = 0x87
    103      1.1  christos #define	F_0NZC		msp430->flags_1 = 0; msp430->flags_0 = 0x80; msp430->flags_set = 0x07
    104      1.1  christos 
    105      1.1  christos 
    106      1.1  christos /* The chip is little-endian, but GETBYTE byte-swaps words because the
    107      1.1  christos    decoder is based on 16-bit "words" so *this* logic is big-endian.  */
    108      1.1  christos 
    109      1.1  christos static int
    110      1.1  christos immediate (int bytes, int sign_extend, LocalData *ld)
    111      1.1  christos {
    112      1.1  christos   unsigned long i = 0;
    113      1.1  christos 
    114      1.1  christos   switch (bytes)
    115      1.1  christos     {
    116      1.1  christos     case 1:
    117      1.1  christos       i |= B;
    118      1.1  christos       if (sign_extend && (i & 0x80))
    119      1.1  christos 	i -= 0x100;
    120      1.1  christos       break;
    121      1.1  christos     case 2:
    122      1.1  christos       i |= B << 8;
    123      1.1  christos       i |= B;
    124      1.1  christos       if (sign_extend && (i & 0x8000))
    125      1.1  christos 	i -= 0x10000;
    126      1.1  christos       break;
    127      1.1  christos     case 3:
    128      1.1  christos       i |= B << 16;
    129      1.1  christos       i |= B << 8;
    130      1.1  christos       i |= B;
    131      1.1  christos       if (sign_extend && (i & 0x800000))
    132      1.1  christos 	i -= 0x1000000;
    133      1.1  christos       break;
    134      1.1  christos     case 4:
    135      1.1  christos       i |= B << 24;
    136      1.1  christos       i |= B << 16;
    137      1.1  christos       i |= B << 8;
    138      1.1  christos       i |= B;
    139      1.1  christos       if (sign_extend && (i & 0x80000000ULL))
    140      1.1  christos 	i -= 0x100000000ULL;
    141      1.1  christos       break;
    142      1.1  christos     default:
    143      1.1  christos       fprintf (stderr,
    144      1.1  christos 	       "Programmer error: immediate() called with invalid byte count %d\n",
    145      1.1  christos 	       bytes);
    146      1.1  christos       abort ();
    147      1.1  christos     }
    148      1.1  christos   return i;
    149      1.1  christos }
    150      1.1  christos 
    151      1.1  christos /*
    152      1.1  christos 		PC	SP	SR	CG
    153      1.1  christos   As
    154      1.1  christos   00	Rn	-	-	R2	#0
    155      1.1  christos   01	X(Rn)	Sym	-	X(abs)	#1
    156      1.1  christos   10	(Rn)	-	-	#4	#2
    157      1.1  christos   11	(Rn++)	#imm	-	#8	#-1
    158      1.1  christos 
    159      1.1  christos   Ad
    160      1.1  christos   0	Rn	-	-	-	-
    161      1.1  christos   1	X(Rn)	Sym	-	X(abs)	-   */
    162      1.1  christos 
    163      1.1  christos static void
    164      1.1  christos encode_ad (int reg, int ad, LocalData *ld, int ext)
    165      1.1  christos {
    166      1.1  christos   MSP430_Opcode_Decoded *msp430 = ld->msp430;
    167      1.1  christos 
    168      1.1  christos   if (ad)
    169      1.1  christos     {
    170      1.1  christos       int x = IMMU(2) | (ext << 16);
    171      1.1  christos       switch (reg)
    172      1.1  christos 	{
    173      1.1  christos 	case 0: /* (PC) -> Symbolic.  */
    174      1.1  christos 	  DA (x + ld->pc + ld->op_ptr - 2);
    175      1.1  christos 	  break;
    176      1.1  christos 	case 2: /* (SR) -> Absolute.  */
    177      1.1  christos 	  DA (x);
    178      1.1  christos 	  break;
    179      1.1  christos 	default:
    180      1.1  christos 	  DM (reg, x);
    181      1.1  christos 	  break;
    182      1.1  christos 	}
    183      1.1  christos     }
    184      1.1  christos   else
    185      1.1  christos     {
    186      1.1  christos       DR (reg);
    187      1.1  christos     }
    188      1.1  christos }
    189      1.1  christos 
    190      1.1  christos static void
    191      1.1  christos encode_as (int reg, int as, LocalData *ld, int ext)
    192      1.1  christos {
    193      1.1  christos   MSP430_Opcode_Decoded *msp430 = ld->msp430;
    194      1.1  christos   int x;
    195      1.1  christos 
    196      1.1  christos   switch (as)
    197      1.1  christos     {
    198      1.1  christos     case 0:
    199      1.1  christos       switch (reg)
    200      1.1  christos 	{
    201      1.1  christos 	case 3:
    202      1.1  christos 	  SC (0);
    203      1.1  christos 	  break;
    204      1.1  christos 	default:
    205      1.1  christos 	  SR (reg);
    206      1.1  christos 	  break;
    207      1.1  christos 	}
    208      1.1  christos       break;
    209      1.1  christos     case 1:
    210      1.1  christos       switch (reg)
    211      1.1  christos 	{
    212      1.1  christos 	case 0: /* PC -> Symbolic.  */
    213      1.1  christos 	  x = IMMU(2) | (ext << 16);
    214      1.1  christos 	  SA (x + ld->pc + ld->op_ptr - 2);
    215      1.1  christos 	  break;
    216      1.1  christos 	case 2: /* SR -> Absolute.  */
    217      1.1  christos 	  x = IMMU(2) | (ext << 16);
    218      1.1  christos 	  SA (x);
    219      1.1  christos 	  break;
    220      1.1  christos 	case 3:
    221      1.1  christos 	  SC (1);
    222      1.1  christos 	  break;
    223      1.1  christos 	default:
    224      1.1  christos 	  x = IMMU(2) | (ext << 16);
    225      1.1  christos 	  SM (reg, x);
    226      1.1  christos 	  break;
    227      1.1  christos 	}
    228      1.1  christos       break;
    229      1.1  christos     case 2:
    230      1.1  christos       switch (reg)
    231      1.1  christos 	{
    232      1.1  christos 	case 2:
    233      1.1  christos 	  SC (4);
    234      1.1  christos 	  break;
    235      1.1  christos 	case 3:
    236      1.1  christos 	  SC (2);
    237      1.1  christos 	  break;
    238      1.1  christos 	case MSR_None:
    239      1.1  christos 	  SA (0);
    240      1.1  christos 	default:
    241      1.1  christos 	  SM (reg, 0);
    242      1.1  christos 	  break;
    243      1.1  christos 	}
    244      1.1  christos       break;
    245      1.1  christos     case 3:
    246      1.1  christos       switch (reg)
    247      1.1  christos 	{
    248      1.1  christos 	case 0:
    249      1.1  christos 	  {
    250      1.1  christos 	    /* This fetch *is* the *PC++ that the opcode encodes :-)  */
    251      1.1  christos 	    x = IMMU(2) | (ext << 16);
    252      1.1  christos 	    SC (x);
    253      1.1  christos 	  }
    254      1.1  christos 	  break;
    255      1.1  christos 	case 2:
    256      1.1  christos 	  SC (8);
    257      1.1  christos 	  break;
    258      1.1  christos 	case 3:
    259      1.1  christos 	  SC (-1);
    260      1.1  christos 	  break;
    261      1.1  christos 	default:
    262      1.1  christos 	  SI (reg);
    263      1.1  christos 	  break;
    264      1.1  christos 	}
    265      1.1  christos       break;
    266      1.1  christos     }
    267      1.1  christos }
    268      1.1  christos 
    269      1.1  christos static void
    270      1.1  christos encode_rep_zc (int srxt, int dsxt, LocalData *ld)
    271      1.1  christos {
    272      1.1  christos   MSP430_Opcode_Decoded *msp430 = ld->msp430;
    273      1.1  christos 
    274      1.1  christos   msp430->repeat_reg = srxt & 1;
    275      1.1  christos   msp430->repeats = dsxt;
    276      1.1  christos   msp430->zc = (srxt & 2) ? 1 : 0;
    277      1.1  christos }
    278      1.1  christos 
    279      1.1  christos #define REPZC(s,d) encode_rep_zc (s, d, ld)
    280      1.1  christos 
    281      1.1  christos static int
    282      1.1  christos dopc_to_id (int dopc)
    283      1.1  christos {
    284      1.1  christos   switch (dopc)
    285      1.1  christos     {
    286      1.1  christos     case 4: return MSO_mov;
    287      1.1  christos     case 5: return MSO_add;
    288      1.1  christos     case 6: return MSO_addc;
    289      1.1  christos     case 7: return MSO_subc;
    290      1.1  christos     case 8: return MSO_sub;
    291      1.1  christos     case 9: return MSO_cmp;
    292      1.1  christos     case 10: return MSO_dadd;
    293      1.1  christos     case 11: return MSO_bit;
    294      1.1  christos     case 12: return MSO_bic;
    295      1.1  christos     case 13: return MSO_bis;
    296      1.1  christos     case 14: return MSO_xor;
    297      1.1  christos     case 15: return MSO_and;
    298      1.1  christos     default: return MSO_unknown;
    299      1.1  christos     }
    300      1.1  christos }
    301      1.1  christos 
    302      1.1  christos static int
    303      1.1  christos sopc_to_id (int sop, int c)
    304      1.1  christos {
    305      1.1  christos   switch (sop * 2 + c)
    306      1.1  christos     {
    307      1.1  christos     case 0: return MSO_rrc;
    308      1.1  christos     case 1: return MSO_swpb;
    309      1.1  christos     case 2: return MSO_rra;
    310      1.1  christos     case 3: return MSO_sxt;
    311      1.1  christos     case 4: return MSO_push;
    312      1.1  christos     case 5: return MSO_call;
    313      1.1  christos     case 6: return MSO_reti;
    314      1.1  christos     default: return MSO_unknown;
    315      1.1  christos     }
    316      1.1  christos }
    317      1.1  christos 
    318      1.1  christos int
    319      1.1  christos msp430_decode_opcode (unsigned long pc,
    320      1.1  christos 		      MSP430_Opcode_Decoded *msp430,
    321      1.1  christos 		      int (*getbyte)(void *),
    322      1.1  christos 		      void *ptr)
    323      1.1  christos {
    324      1.1  christos   LocalData lds, *ld = &lds;
    325      1.1  christos   unsigned char op_buf[20] = {0};
    326      1.1  christos   unsigned char *op = op_buf;
    327      1.1  christos   int raddr;
    328      1.1  christos   int al_bit;
    329      1.1  christos   int srxt_bits, dsxt_bits;
    330      1.1  christos 
    331      1.1  christos   lds.msp430 = msp430;
    332      1.1  christos   lds.getbyte = getbyte;
    333      1.1  christos   lds.ptr = ptr;
    334      1.1  christos   lds.op = op;
    335      1.1  christos   lds.op_ptr = 0;
    336      1.1  christos   lds.pc = pc;
    337      1.1  christos 
    338      1.1  christos   memset (msp430, 0, sizeof (*msp430));
    339      1.1  christos 
    340      1.1  christos   /* These are overridden by an extension word.  */
    341      1.1  christos   al_bit = 1;
    342      1.1  christos   srxt_bits = 0;
    343      1.1  christos   dsxt_bits = 0;
    344      1.1  christos 
    345      1.1  christos  post_extension_word:
    346      1.1  christos   ;
    347      1.1  christos 
    348      1.1  christos   /* 430X extention word.  */
    349      1.1  christos /** 0001 1srx t l 00 dsxt 	430x */
    350      1.1  christos 
    351      1.1  christos   al_bit = l;
    352      1.1  christos   srxt_bits = srx * 2 + t;
    353      1.1  christos   dsxt_bits = dsxt;
    354      1.1  christos   op = op_buf + lds.op_ptr;
    355      1.1  christos   msp430->ofs_430x = 1;
    356      1.1  christos   goto post_extension_word;
    357      1.1  christos 
    358      1.1  christos /* double-op insns:
    359      1.1  christos    opcode:4 sreg:4 Ad:1 BW:1 As:2 Dreg:4
    360      1.1  christos 
    361      1.1  christos    single-op insn:
    362      1.1  christos    opcode:9 BW:1 Ad:2 DSreg:4
    363      1.1  christos 
    364      1.1  christos    jumps:
    365      1.1  christos    opcode:3 Cond:3  pcrel:10. */
    366      1.1  christos 
    367      1.1  christos /* Double-Operand "opcode" fields.  */
    368      1.1  christos /** VARY dopc 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 */
    369      1.1  christos 
    370      1.1  christos /** dopc sreg a b as dreg	%D%b	%1,%0				*/
    371      1.1  christos 
    372      1.1  christos   ID (dopc_to_id (dopc)); ASX (sreg, as, srxt_bits); ADX (dreg, a, dsxt_bits); ABW (al_bit, b);
    373      1.1  christos   if (a == 0 && as == 0)
    374      1.1  christos     REPZC (srxt_bits, dsxt_bits);
    375      1.1  christos 
    376      1.1  christos   switch (msp430->id)
    377      1.1  christos     {
    378      1.1  christos     case MSO_mov:	F_____; break;
    379      1.1  christos     case MSO_add:	F_VNZC; break;
    380      1.1  christos     case MSO_addc:	F_VNZC; break;
    381      1.1  christos     case MSO_subc:	F_VNZC; break;
    382      1.1  christos     case MSO_sub:	F_VNZC; break;
    383      1.1  christos     case MSO_cmp:	F_VNZC; break;
    384      1.1  christos     case MSO_dadd:	F_VNZC; break;
    385      1.1  christos     case MSO_bit:	F_0NZC; break;
    386      1.1  christos     case MSO_bic:	F_____; break;
    387      1.1  christos     case MSO_bis:	F_____; break;
    388      1.1  christos     case MSO_xor:	F_VNZC; break;
    389      1.1  christos     case MSO_and:	F_0NZC; break;
    390      1.1  christos     default: break;
    391      1.1  christos     }
    392      1.1  christos 
    393      1.1  christos /** 0001 00so c b ad dreg	%S%b	%1				*/
    394      1.1  christos 
    395      1.1  christos   ID (sopc_to_id (so,c)); ASX (dreg, ad, srxt_bits); ABW (al_bit, b);
    396      1.1  christos 
    397      1.1  christos   if (ad == 0)
    398      1.1  christos     REPZC (srxt_bits, dsxt_bits);
    399      1.1  christos 
    400      1.1  christos   /* The helper functions encode for source, but it's
    401      1.1  christos      both source and dest, with a few documented exceptions.  */
    402      1.1  christos   msp430->op[0] = msp430->op[1];
    403      1.1  christos 
    404      1.1  christos   /* RETI ignores the operand.  */
    405      1.1  christos   if (msp430->id == MSO_reti)
    406      1.1  christos     msp430->syntax = "%S";
    407      1.1  christos 
    408      1.1  christos   switch (msp430->id)
    409      1.1  christos     {
    410      1.1  christos     case MSO_rrc:	F_VNZC; break;
    411      1.1  christos     case MSO_swpb:	F_____; break;
    412      1.1  christos     case MSO_rra:	F_0NZC; break;
    413      1.1  christos     case MSO_sxt:	F_0NZC; break;
    414      1.1  christos     case MSO_push:	F_____; break;
    415      1.1  christos     case MSO_call:	F_____; break;
    416      1.1  christos     case MSO_reti:	F_VNZC; break;
    417      1.1  christos     default: break;
    418      1.1  christos     }
    419      1.1  christos 
    420      1.1  christos   /* 20xx 0010 0000 ---- ----
    421      1.1  christos      3cxx 0011 1100 ---- ----
    422      1.1  christos           001j mp-- ---- ----.  */
    423      1.1  christos /** 001jmp aa addrlsbs		%J	%1				*/
    424      1.1  christos 
    425      1.1  christos   raddr = (aa << 9) | (addrlsbs << 1);
    426      1.1  christos   if (raddr & 0x400)
    427      1.1  christos     raddr = raddr - 0x800;
    428      1.1  christos   /* This is a pc-relative jump, but we don't use SM because that
    429      1.1  christos      would load the target address from the memory at X(PC), not use
    430      1.1  christos      PC+X *as* the address.  So we use SC to use the address, not the
    431      1.1  christos      data at that address.  */
    432      1.1  christos   ID (MSO_jmp); SC (pc + raddr + msp430->n_bytes);
    433      1.1  christos   msp430->cond = jmp;
    434      1.1  christos 
    435      1.1  christos   /* Extended instructions.  */
    436      1.1  christos 
    437      1.1  christos /** 0000 srcr 0000 dstr		MOVA @%1, %0 */
    438      1.1  christos   ID (MSO_mov); SM (srcr, 0); DR (dstr);
    439      1.1  christos   msp430->size = 20;
    440      1.1  christos   msp430->ofs_430x = 1;
    441      1.1  christos 
    442      1.1  christos /** 0000 srcr 0001 dstr		MOVA @%1+, %0 */
    443      1.1  christos   ID (MSO_mov); SI (srcr); DR (dstr);
    444      1.1  christos   msp430->size = 20;
    445      1.1  christos   msp430->ofs_430x = 1;
    446      1.1  christos 
    447      1.1  christos /** 0000 srcr 0010 dstr		MOVA &%1, %0 */
    448      1.1  christos   ID (MSO_mov); SA ((srcr << 16) + IMMU(2)); DR (dstr);
    449      1.1  christos   msp430->size = 20;
    450      1.1  christos   msp430->ofs_430x = 1;
    451      1.1  christos 
    452      1.1  christos /** 0000 srcr 0011 dstr		MOVA %1, %0 */
    453      1.1  christos   ID (MSO_mov); SM (srcr, IMMS(2)); DR (dstr);
    454      1.1  christos   msp430->size = 20;
    455      1.1  christos   msp430->ofs_430x = 1;
    456      1.1  christos 
    457      1.1  christos /** 0000 srcr 0110 dstr		MOVA %1, &%0 */
    458      1.1  christos   ID (MSO_mov); SR (srcr); DA ((dstr << 16) + IMMU(2));
    459      1.1  christos   msp430->size = 20;
    460      1.1  christos   msp430->ofs_430x = 1;
    461      1.1  christos 
    462      1.1  christos /** 0000 srcr 0111 dstr		MOVA %1, &%0 */
    463      1.1  christos   ID (MSO_mov); SR (srcr); DM (dstr, IMMS(2));
    464      1.1  christos   msp430->size = 20;
    465      1.1  christos   msp430->ofs_430x = 1;
    466      1.1  christos 
    467      1.1  christos /** 0000 srcr 1000 dstr		MOVA %1, %0 */
    468      1.1  christos   ID (MSO_mov); SC ((srcr << 16) + IMMU(2)); DR (dstr);
    469      1.1  christos   msp430->size = 20;
    470      1.1  christos   msp430->ofs_430x = 1;
    471      1.1  christos 
    472      1.1  christos /** 0000 srcr 1001 dstr		CMPA %1, %0 */
    473      1.1  christos   ID (MSO_cmp); SC ((srcr << 16) + IMMU(2)); DR (dstr);
    474      1.1  christos   msp430->size = 20;
    475      1.1  christos   msp430->ofs_430x = 1;
    476      1.1  christos   F_VNZC;
    477      1.1  christos 
    478      1.1  christos /** 0000 srcr 1010 dstr		ADDA %1, %0 */
    479      1.1  christos   ID (MSO_add); SC ((srcr << 16) + IMMU(2)); DR (dstr);
    480      1.1  christos   msp430->size = 20;
    481      1.1  christos   msp430->ofs_430x = 1;
    482      1.1  christos   F_VNZC;
    483      1.1  christos 
    484      1.1  christos /** 0000 srcr 1011 dstr		SUBA %1, %0 */
    485      1.1  christos   ID (MSO_sub); SC ((srcr << 16) + IMMU(2)); DR (dstr);
    486      1.1  christos   msp430->size = 20;
    487      1.1  christos   msp430->ofs_430x = 1;
    488      1.1  christos   F_VNZC;
    489      1.1  christos 
    490      1.1  christos /** 0000 srcr 1011 dstr		SUBA %1, %0 */
    491      1.1  christos   ID (MSO_sub); SC ((srcr << 16) + IMMU(2)); DR (dstr);
    492      1.1  christos   msp430->size = 20;
    493      1.1  christos   msp430->ofs_430x = 1;
    494      1.1  christos   F_VNZC;
    495      1.1  christos 
    496      1.1  christos /** 0000 srcr 1100 dstr		MOVA %1, %0 */
    497      1.1  christos   ID (MSO_mov); SR (srcr); DR (dstr);
    498      1.1  christos   msp430->size = 20;
    499      1.1  christos   msp430->ofs_430x = 1;
    500      1.1  christos 
    501      1.1  christos /** 0000 srcr 1101 dstr		CMPA %1, %0 */
    502      1.1  christos   ID (MSO_cmp); SR (srcr); DR (dstr);
    503      1.1  christos   msp430->size = 20;
    504      1.1  christos   msp430->ofs_430x = 1;
    505      1.1  christos   F_VNZC;
    506      1.1  christos 
    507      1.1  christos /** 0000 srcr 1110 dstr		ADDA %1, %0 */
    508      1.1  christos   ID (MSO_add); SR (srcr); DR (dstr);
    509      1.1  christos   msp430->size = 20;
    510      1.1  christos   msp430->ofs_430x = 1;
    511      1.1  christos   F_VNZC;
    512      1.1  christos 
    513      1.1  christos /** 0000 srcr 1111 dstr		SUBA %1, %0 */
    514      1.1  christos   ID (MSO_sub); SR (srcr); DR (dstr);
    515      1.1  christos   msp430->size = 20;
    516      1.1  christos   msp430->ofs_430x = 1;
    517      1.1  christos   F_VNZC;
    518      1.1  christos 
    519      1.1  christos /** 0000 bt00 010w dstr		RRCM.A %c, %0 */
    520      1.1  christos   ID (MSO_rrc); DR (dstr); SR (dstr);
    521      1.1  christos   msp430->repeats = bt;
    522      1.1  christos   msp430->size = w ? 16 : 20;
    523      1.1  christos   msp430->ofs_430x = 1;
    524      1.1  christos   F_0NZC;
    525      1.1  christos 
    526      1.1  christos /** 0000 bt01 010w dstr		RRAM.A %c, %0 */
    527      1.1  christos   ID (MSO_rra); DR (dstr); SR (dstr);
    528      1.1  christos   msp430->repeats = bt;
    529      1.1  christos   msp430->size = w ? 16 : 20;
    530      1.1  christos   msp430->ofs_430x = 1;
    531      1.1  christos   F_0NZC;
    532      1.1  christos 
    533      1.1  christos /** 0000 bt10 010w dstr		RLAM.A %c, %0 */
    534      1.1  christos   ID (MSO_add); DR (dstr); SR (dstr);
    535      1.1  christos   msp430->repeats = bt;
    536      1.1  christos   msp430->size = w ? 16 : 20;
    537      1.1  christos   msp430->ofs_430x = 1;
    538      1.1  christos   F_0NZC;
    539      1.1  christos 
    540      1.1  christos /** 0000 bt11 010w dstr		RRUM.A %c, %0 */
    541      1.1  christos   ID (MSO_rru); DR (dstr); SR (dstr);
    542      1.1  christos   msp430->repeats = bt;
    543      1.1  christos   msp430->size = w ? 16 : 20;
    544      1.1  christos   msp430->ofs_430x = 1;
    545      1.1  christos   F_0NZC;
    546      1.1  christos 
    547      1.1  christos /** 0001 0011 0000 0000		RETI */
    548      1.1  christos   ID (MSO_reti);
    549      1.1  christos   msp430->size = 20;
    550      1.1  christos   msp430->ofs_430x = 1;
    551      1.1  christos 
    552      1.1  christos /** 0001 0011 01as dstr		CALLA %0 */
    553      1.1  christos   ID (MSO_call); AS (dstr, as);
    554      1.1  christos   msp430->size = 20;
    555      1.1  christos   msp430->ofs_430x = 1;
    556      1.1  christos 
    557      1.1  christos /** 0001 0011 1000 extb		CALLA %0 */
    558      1.1  christos   ID (MSO_call); SA (IMMU(2) | (extb << 16));
    559      1.1  christos   msp430->size = 20;
    560      1.1  christos   msp430->ofs_430x = 1;
    561      1.1  christos 
    562      1.1  christos /** 0001 0011 1001 extb		CALLA %0 */
    563      1.1  christos   raddr = IMMU(2) | (extb << 16);
    564      1.1  christos   if (raddr & 0x80000)
    565      1.1  christos     raddr -= 0x100000;
    566      1.1  christos   ID (MSO_call); SA (pc + raddr + msp430->n_bytes);
    567      1.1  christos   msp430->size = 20;
    568      1.1  christos   msp430->ofs_430x = 1;
    569      1.1  christos 
    570      1.1  christos /** 0001 0011 1011 extb		CALLA %0 */
    571      1.1  christos   ID (MSO_call); SC (IMMU(2) | (extb << 16));
    572      1.1  christos   msp430->size = 20;
    573      1.1  christos   msp430->ofs_430x = 1;
    574      1.1  christos 
    575      1.1  christos /** 0001 010w bits srcr		PUSHM.A %0 */
    576      1.1  christos   ID (MSO_push); SR (srcr);
    577      1.1  christos   msp430->size = w ? 16 : 20;
    578      1.1  christos   msp430->repeats = bits;
    579      1.1  christos   msp430->ofs_430x = 1;
    580      1.1  christos 
    581      1.1  christos /** 0001 011w bits dstr		POPM.A %0 */
    582      1.1  christos   ID (MSO_pop); DR (dstr);
    583      1.1  christos   msp430->size = w ? 16 : 20;
    584      1.1  christos   msp430->repeats = bits;
    585      1.1  christos   msp430->ofs_430x = 1;
    586      1.1  christos 
    587      1.1  christos /** */
    588      1.1  christos 
    589      1.1  christos   return msp430->n_bytes;
    590      1.1  christos }
    591