xref: /netbsd-src/external/gpl3/binutils.old/dist/opcodes/msp430-decode.opc (revision e992f068c547fd6e84b3f104dc2340adcc955732)
175fd0b74Schristos/* -*- c -*- */
2*e992f068Schristos/* Copyright (C) 2013-2022 Free Software Foundation, Inc.
375fd0b74Schristos   Contributed by Red Hat.
475fd0b74Schristos   Written by DJ Delorie.
575fd0b74Schristos
675fd0b74Schristos   This file is part of the GNU opcodes library.
775fd0b74Schristos
875fd0b74Schristos   This library is free software; you can redistribute it and/or modify
975fd0b74Schristos   it under the terms of the GNU General Public License as published by
1075fd0b74Schristos   the Free Software Foundation; either version 3, or (at your option)
1175fd0b74Schristos   any later version.
1275fd0b74Schristos
1375fd0b74Schristos   It is distributed in the hope that it will be useful, but WITHOUT
1475fd0b74Schristos   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1575fd0b74Schristos   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
1675fd0b74Schristos   License for more details.
1775fd0b74Schristos
1875fd0b74Schristos   You should have received a copy of the GNU General Public License
1975fd0b74Schristos   along with this program; if not, write to the Free Software
2075fd0b74Schristos   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
2175fd0b74Schristos   MA 02110-1301, USA.  */
2275fd0b74Schristos
2375fd0b74Schristos#include "sysdep.h"
2475fd0b74Schristos#include <stdio.h>
2575fd0b74Schristos#include <stdlib.h>
2675fd0b74Schristos#include <string.h>
27ede78133Schristos#include "bfd.h"
28ede78133Schristos#include "opintl.h"
2975fd0b74Schristos#include "opcode/msp430-decode.h"
3075fd0b74Schristos
3175fd0b74Schristosstatic int trace = 0;
3275fd0b74Schristos
3375fd0b74Schristostypedef struct
3475fd0b74Schristos{
3575fd0b74Schristos  MSP430_Opcode_Decoded *msp430;
3675fd0b74Schristos  int (*getbyte)(void *);
3775fd0b74Schristos  void *ptr;
3875fd0b74Schristos  unsigned char *op;
3975fd0b74Schristos  int op_ptr;
4075fd0b74Schristos  int pc;
4175fd0b74Schristos} LocalData;
4275fd0b74Schristos
4375fd0b74Schristos#define AU ATTRIBUTE_UNUSED
4475fd0b74Schristos#define GETBYTE() getbyte_swapped (ld)
4575fd0b74Schristos#define B ((unsigned long) GETBYTE ())
4675fd0b74Schristos
4775fd0b74Schristosstatic int
4875fd0b74Schristosgetbyte_swapped (LocalData *ld)
4975fd0b74Schristos{
5075fd0b74Schristos  int b;
5175fd0b74Schristos
5275fd0b74Schristos  if (ld->op_ptr == ld->msp430->n_bytes)
5375fd0b74Schristos    {
5475fd0b74Schristos      do
5575fd0b74Schristos	{
5675fd0b74Schristos	  b = ld->getbyte (ld->ptr);
5775fd0b74Schristos	  ld->op [(ld->msp430->n_bytes++)^1] = b;
5875fd0b74Schristos	}
5975fd0b74Schristos      while (ld->msp430->n_bytes & 1);
6075fd0b74Schristos    }
6175fd0b74Schristos  return ld->op[ld->op_ptr++];
6275fd0b74Schristos}
6375fd0b74Schristos
6475fd0b74Schristos#define ID(x)		msp430->id = x
6575fd0b74Schristos
6675fd0b74Schristos#define OP(n, t, r, a) (msp430->op[n].type = t,	     \
6775fd0b74Schristos		        msp430->op[n].reg = r,	     \
6875fd0b74Schristos		        msp430->op[n].addend = a)
6975fd0b74Schristos
7075fd0b74Schristos#define OPX(n, t, r1, r2, a)	 \
7175fd0b74Schristos  (msp430->op[n].type = t,	 \
7275fd0b74Schristos   msp430->op[n].reg = r1,	 \
7375fd0b74Schristos   msp430->op[n].reg2 = r2,	 \
7475fd0b74Schristos   msp430->op[n].addend = a)
7575fd0b74Schristos
7675fd0b74Schristos#define SYNTAX(x)	msp430->syntax = x
7775fd0b74Schristos#define UNSUPPORTED()	msp430->syntax = "*unknown*"
7875fd0b74Schristos
7975fd0b74Schristos#define DC(c)		OP (0, MSP430_Operand_Immediate, 0, c)
8075fd0b74Schristos#define DR(r)		OP (0, MSP430_Operand_Register, r, 0)
8175fd0b74Schristos#define DM(r, a)	OP (0, MSP430_Operand_Indirect, r, a)
8275fd0b74Schristos#define DA(a)		OP (0, MSP430_Operand_Indirect, MSR_None, a)
8375fd0b74Schristos#define AD(r, ad)	encode_ad (r, ad, ld, 0)
8475fd0b74Schristos#define ADX(r, ad, x)	encode_ad (r, ad, ld, x)
8575fd0b74Schristos
8675fd0b74Schristos#define SC(c)		OP (1, MSP430_Operand_Immediate, 0, c)
8775fd0b74Schristos#define SR(r)		OP (1, MSP430_Operand_Register, r, 0)
8875fd0b74Schristos#define SM(r, a)	OP (1, MSP430_Operand_Indirect, r, a)
8975fd0b74Schristos#define SA(a)		OP (1, MSP430_Operand_Indirect, MSR_None, a)
9075fd0b74Schristos#define SI(r)		OP (1, MSP430_Operand_Indirect_Postinc, r, 0)
9175fd0b74Schristos#define AS(r, as)	encode_as (r, as, ld, 0)
9275fd0b74Schristos#define ASX(r, as, x)	encode_as (r, as, ld, x)
9375fd0b74Schristos
9475fd0b74Schristos#define BW(x)		msp430->size = (x ? 8 : 16)
9575fd0b74Schristos/* The last 20 is for SWPBX.Z and SXTX.A.  */
9675fd0b74Schristos#define ABW(a,x)	msp430->size = (a ? ((x ? 8 : 16)) : (x ? 20 : 20))
9775fd0b74Schristos
9875fd0b74Schristos#define IMMU(bytes)	immediate (bytes, 0, ld)
9975fd0b74Schristos#define IMMS(bytes)	immediate (bytes, 1, ld)
10075fd0b74Schristos
10175fd0b74Schristos/* Helper macros for known status bits settings.  */
10275fd0b74Schristos#define	F_____		msp430->flags_1 = msp430->flags_0 = 0; msp430->flags_set = 0
10375fd0b74Schristos#define	F_VNZC		msp430->flags_1 = msp430->flags_0 = 0; msp430->flags_set = 0x87
10475fd0b74Schristos#define	F_0NZC		msp430->flags_1 = 0; msp430->flags_0 = 0x80; msp430->flags_set = 0x07
10575fd0b74Schristos
10675fd0b74Schristos
10775fd0b74Schristos/* The chip is little-endian, but GETBYTE byte-swaps words because the
10875fd0b74Schristos   decoder is based on 16-bit "words" so *this* logic is big-endian.  */
10975fd0b74Schristos
11075fd0b74Schristosstatic int
11175fd0b74Schristosimmediate (int bytes, int sign_extend, LocalData *ld)
11275fd0b74Schristos{
11375fd0b74Schristos  unsigned long i = 0;
11475fd0b74Schristos
11575fd0b74Schristos  switch (bytes)
11675fd0b74Schristos    {
11775fd0b74Schristos    case 1:
11875fd0b74Schristos      i |= B;
11975fd0b74Schristos      if (sign_extend && (i & 0x80))
12075fd0b74Schristos	i -= 0x100;
12175fd0b74Schristos      break;
12275fd0b74Schristos    case 2:
12375fd0b74Schristos      i |= B << 8;
12475fd0b74Schristos      i |= B;
12575fd0b74Schristos      if (sign_extend && (i & 0x8000))
12675fd0b74Schristos	i -= 0x10000;
12775fd0b74Schristos      break;
12875fd0b74Schristos    case 3:
12975fd0b74Schristos      i |= B << 16;
13075fd0b74Schristos      i |= B << 8;
13175fd0b74Schristos      i |= B;
13275fd0b74Schristos      if (sign_extend && (i & 0x800000))
13375fd0b74Schristos	i -= 0x1000000;
13475fd0b74Schristos      break;
13575fd0b74Schristos    case 4:
13675fd0b74Schristos      i |= B << 24;
13775fd0b74Schristos      i |= B << 16;
13875fd0b74Schristos      i |= B << 8;
13975fd0b74Schristos      i |= B;
14075fd0b74Schristos      if (sign_extend && (i & 0x80000000ULL))
14175fd0b74Schristos	i -= 0x100000000ULL;
14275fd0b74Schristos      break;
14375fd0b74Schristos    default:
144ede78133Schristos      opcodes_error_handler
145ede78133Schristos	(_("internal error: immediate() called with invalid byte count %d"),
14675fd0b74Schristos	   bytes);
14775fd0b74Schristos      abort ();
14875fd0b74Schristos    }
14975fd0b74Schristos  return i;
15075fd0b74Schristos}
15175fd0b74Schristos
15275fd0b74Schristos/*
15375fd0b74Schristos		PC	SP	SR	CG
15475fd0b74Schristos  As
15575fd0b74Schristos  00	Rn	-	-	R2	#0
15675fd0b74Schristos  01	X(Rn)	Sym	-	X(abs)	#1
15775fd0b74Schristos  10	(Rn)	-	-	#4	#2
15875fd0b74Schristos  11	(Rn++)	#imm	-	#8	#-1
15975fd0b74Schristos
16075fd0b74Schristos  Ad
16175fd0b74Schristos  0	Rn	-	-	-	-
16275fd0b74Schristos  1	X(Rn)	Sym	-	X(abs)	-   */
16375fd0b74Schristos
16475fd0b74Schristosstatic void
16575fd0b74Schristosencode_ad (int reg, int ad, LocalData *ld, int ext)
16675fd0b74Schristos{
16775fd0b74Schristos  MSP430_Opcode_Decoded *msp430 = ld->msp430;
16875fd0b74Schristos
16975fd0b74Schristos  if (ad)
17075fd0b74Schristos    {
17175fd0b74Schristos      int x = IMMU(2) | (ext << 16);
17275fd0b74Schristos      switch (reg)
17375fd0b74Schristos	{
17475fd0b74Schristos	case 0: /* (PC) -> Symbolic.  */
17575fd0b74Schristos	  DA (x + ld->pc + ld->op_ptr - 2);
17675fd0b74Schristos	  break;
17775fd0b74Schristos	case 2: /* (SR) -> Absolute.  */
17875fd0b74Schristos	  DA (x);
17975fd0b74Schristos	  break;
18075fd0b74Schristos	default:
18175fd0b74Schristos	  DM (reg, x);
18275fd0b74Schristos	  break;
18375fd0b74Schristos	}
18475fd0b74Schristos    }
18575fd0b74Schristos  else
18675fd0b74Schristos    {
18775fd0b74Schristos      DR (reg);
18875fd0b74Schristos    }
18975fd0b74Schristos}
19075fd0b74Schristos
19175fd0b74Schristosstatic void
19275fd0b74Schristosencode_as (int reg, int as, LocalData *ld, int ext)
19375fd0b74Schristos{
19475fd0b74Schristos  MSP430_Opcode_Decoded *msp430 = ld->msp430;
19575fd0b74Schristos  int x;
19675fd0b74Schristos
19775fd0b74Schristos  switch (as)
19875fd0b74Schristos    {
19975fd0b74Schristos    case 0:
20075fd0b74Schristos      switch (reg)
20175fd0b74Schristos	{
20275fd0b74Schristos	case 3:
20375fd0b74Schristos	  SC (0);
20475fd0b74Schristos	  break;
20575fd0b74Schristos	default:
20675fd0b74Schristos	  SR (reg);
20775fd0b74Schristos	  break;
20875fd0b74Schristos	}
20975fd0b74Schristos      break;
21075fd0b74Schristos    case 1:
21175fd0b74Schristos      switch (reg)
21275fd0b74Schristos	{
21375fd0b74Schristos	case 0: /* PC -> Symbolic.  */
21475fd0b74Schristos	  x = IMMU(2) | (ext << 16);
21575fd0b74Schristos	  SA (x + ld->pc + ld->op_ptr - 2);
21675fd0b74Schristos	  break;
21775fd0b74Schristos	case 2: /* SR -> Absolute.  */
21875fd0b74Schristos	  x = IMMU(2) | (ext << 16);
21975fd0b74Schristos	  SA (x);
22075fd0b74Schristos	  break;
22175fd0b74Schristos	case 3:
22275fd0b74Schristos	  SC (1);
22375fd0b74Schristos	  break;
22475fd0b74Schristos	default:
22575fd0b74Schristos	  x = IMMU(2) | (ext << 16);
22675fd0b74Schristos	  SM (reg, x);
22775fd0b74Schristos	  break;
22875fd0b74Schristos	}
22975fd0b74Schristos      break;
23075fd0b74Schristos    case 2:
23175fd0b74Schristos      switch (reg)
23275fd0b74Schristos	{
23375fd0b74Schristos	case 2:
23475fd0b74Schristos	  SC (4);
23575fd0b74Schristos	  break;
23675fd0b74Schristos	case 3:
23775fd0b74Schristos	  SC (2);
23875fd0b74Schristos	  break;
23975fd0b74Schristos	case MSR_None:
24075fd0b74Schristos	  SA (0);
241ede78133Schristos	  break;
24275fd0b74Schristos	default:
24375fd0b74Schristos	  SM (reg, 0);
24475fd0b74Schristos	  break;
24575fd0b74Schristos	}
24675fd0b74Schristos      break;
24775fd0b74Schristos    case 3:
24875fd0b74Schristos      switch (reg)
24975fd0b74Schristos	{
25075fd0b74Schristos	case 0:
25175fd0b74Schristos	  {
25275fd0b74Schristos	    /* This fetch *is* the *PC++ that the opcode encodes :-)  */
25375fd0b74Schristos	    x = IMMU(2) | (ext << 16);
25475fd0b74Schristos	    SC (x);
25575fd0b74Schristos	  }
25675fd0b74Schristos	  break;
25775fd0b74Schristos	case 2:
25875fd0b74Schristos	  SC (8);
25975fd0b74Schristos	  break;
26075fd0b74Schristos	case 3:
26175fd0b74Schristos	  SC (-1);
26275fd0b74Schristos	  break;
26375fd0b74Schristos	default:
26475fd0b74Schristos	  SI (reg);
26575fd0b74Schristos	  break;
26675fd0b74Schristos	}
26775fd0b74Schristos      break;
26875fd0b74Schristos    }
26975fd0b74Schristos}
27075fd0b74Schristos
27175fd0b74Schristosstatic void
27275fd0b74Schristosencode_rep_zc (int srxt, int dsxt, LocalData *ld)
27375fd0b74Schristos{
27475fd0b74Schristos  MSP430_Opcode_Decoded *msp430 = ld->msp430;
27575fd0b74Schristos
27675fd0b74Schristos  msp430->repeat_reg = srxt & 1;
27775fd0b74Schristos  msp430->repeats = dsxt;
27875fd0b74Schristos  msp430->zc = (srxt & 2) ? 1 : 0;
27975fd0b74Schristos}
28075fd0b74Schristos
28175fd0b74Schristos#define REPZC(s,d) encode_rep_zc (s, d, ld)
28275fd0b74Schristos
28375fd0b74Schristosstatic int
28475fd0b74Schristosdopc_to_id (int dopc)
28575fd0b74Schristos{
28675fd0b74Schristos  switch (dopc)
28775fd0b74Schristos    {
28875fd0b74Schristos    case 4: return MSO_mov;
28975fd0b74Schristos    case 5: return MSO_add;
29075fd0b74Schristos    case 6: return MSO_addc;
29175fd0b74Schristos    case 7: return MSO_subc;
29275fd0b74Schristos    case 8: return MSO_sub;
29375fd0b74Schristos    case 9: return MSO_cmp;
29475fd0b74Schristos    case 10: return MSO_dadd;
29575fd0b74Schristos    case 11: return MSO_bit;
29675fd0b74Schristos    case 12: return MSO_bic;
29775fd0b74Schristos    case 13: return MSO_bis;
29875fd0b74Schristos    case 14: return MSO_xor;
29975fd0b74Schristos    case 15: return MSO_and;
30075fd0b74Schristos    default: return MSO_unknown;
30175fd0b74Schristos    }
30275fd0b74Schristos}
30375fd0b74Schristos
30475fd0b74Schristosstatic int
30575fd0b74Schristossopc_to_id (int sop, int c)
30675fd0b74Schristos{
30775fd0b74Schristos  switch (sop * 2 + c)
30875fd0b74Schristos    {
30975fd0b74Schristos    case 0: return MSO_rrc;
31075fd0b74Schristos    case 1: return MSO_swpb;
31175fd0b74Schristos    case 2: return MSO_rra;
31275fd0b74Schristos    case 3: return MSO_sxt;
31375fd0b74Schristos    case 4: return MSO_push;
31475fd0b74Schristos    case 5: return MSO_call;
31575fd0b74Schristos    case 6: return MSO_reti;
31675fd0b74Schristos    default: return MSO_unknown;
31775fd0b74Schristos    }
31875fd0b74Schristos}
31975fd0b74Schristos
32075fd0b74Schristosint
32175fd0b74Schristosmsp430_decode_opcode (unsigned long pc,
32275fd0b74Schristos		      MSP430_Opcode_Decoded *msp430,
32375fd0b74Schristos		      int (*getbyte)(void *),
32475fd0b74Schristos		      void *ptr)
32575fd0b74Schristos{
32675fd0b74Schristos  LocalData lds, *ld = &lds;
32775fd0b74Schristos  unsigned char op_buf[20] = {0};
32875fd0b74Schristos  unsigned char *op = op_buf;
32975fd0b74Schristos  int raddr;
33075fd0b74Schristos  int al_bit;
33175fd0b74Schristos  int srxt_bits, dsxt_bits;
33275fd0b74Schristos
33375fd0b74Schristos  lds.msp430 = msp430;
33475fd0b74Schristos  lds.getbyte = getbyte;
33575fd0b74Schristos  lds.ptr = ptr;
33675fd0b74Schristos  lds.op = op;
33775fd0b74Schristos  lds.op_ptr = 0;
33875fd0b74Schristos  lds.pc = pc;
33975fd0b74Schristos
34075fd0b74Schristos  memset (msp430, 0, sizeof (*msp430));
34175fd0b74Schristos
34275fd0b74Schristos  /* These are overridden by an extension word.  */
34375fd0b74Schristos  al_bit = 1;
34475fd0b74Schristos  srxt_bits = 0;
34575fd0b74Schristos  dsxt_bits = 0;
34675fd0b74Schristos
34775fd0b74Schristos post_extension_word:
34875fd0b74Schristos  ;
34975fd0b74Schristos
35075fd0b74Schristos  /* 430X extention word.  */
35175fd0b74Schristos/** 0001 1srx t l 00 dsxt 	430x */
35275fd0b74Schristos
35375fd0b74Schristos  al_bit = l;
35475fd0b74Schristos  srxt_bits = srx * 2 + t;
35575fd0b74Schristos  dsxt_bits = dsxt;
35675fd0b74Schristos  op = op_buf + lds.op_ptr;
35775fd0b74Schristos  msp430->ofs_430x = 1;
35875fd0b74Schristos  goto post_extension_word;
35975fd0b74Schristos
36075fd0b74Schristos/* double-op insns:
36175fd0b74Schristos   opcode:4 sreg:4 Ad:1 BW:1 As:2 Dreg:4
36275fd0b74Schristos
36375fd0b74Schristos   single-op insn:
36475fd0b74Schristos   opcode:9 BW:1 Ad:2 DSreg:4
36575fd0b74Schristos
36675fd0b74Schristos   jumps:
36775fd0b74Schristos   opcode:3 Cond:3  pcrel:10. */
36875fd0b74Schristos
36975fd0b74Schristos/* Double-Operand "opcode" fields.  */
37075fd0b74Schristos/** VARY dopc 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 */
37175fd0b74Schristos
37275fd0b74Schristos/** dopc sreg a b as dreg	%D%b	%1,%0				*/
37375fd0b74Schristos
37475fd0b74Schristos  ID (dopc_to_id (dopc)); ASX (sreg, as, srxt_bits); ADX (dreg, a, dsxt_bits); ABW (al_bit, b);
37575fd0b74Schristos  if (a == 0 && as == 0)
37675fd0b74Schristos    REPZC (srxt_bits, dsxt_bits);
37775fd0b74Schristos
37875fd0b74Schristos  switch (msp430->id)
37975fd0b74Schristos    {
38075fd0b74Schristos    case MSO_mov:	F_____; break;
38175fd0b74Schristos    case MSO_add:	F_VNZC; break;
38275fd0b74Schristos    case MSO_addc:	F_VNZC; break;
38375fd0b74Schristos    case MSO_subc:	F_VNZC; break;
38475fd0b74Schristos    case MSO_sub:	F_VNZC; break;
38575fd0b74Schristos    case MSO_cmp:	F_VNZC; break;
38675fd0b74Schristos    case MSO_dadd:	F_VNZC; break;
38775fd0b74Schristos    case MSO_bit:	F_0NZC; break;
38875fd0b74Schristos    case MSO_bic:	F_____; break;
38975fd0b74Schristos    case MSO_bis:	F_____; break;
39075fd0b74Schristos    case MSO_xor:	F_VNZC; break;
39175fd0b74Schristos    case MSO_and:	F_0NZC; break;
39275fd0b74Schristos    default: break;
39375fd0b74Schristos    }
39475fd0b74Schristos
39575fd0b74Schristos/** 0001 00so c b ad dreg	%S%b	%1				*/
39675fd0b74Schristos
39775fd0b74Schristos  ID (sopc_to_id (so,c)); ASX (dreg, ad, srxt_bits); ABW (al_bit, b);
39875fd0b74Schristos
39975fd0b74Schristos  if (ad == 0)
40075fd0b74Schristos    REPZC (srxt_bits, dsxt_bits);
40175fd0b74Schristos
40275fd0b74Schristos  /* The helper functions encode for source, but it's
40375fd0b74Schristos     both source and dest, with a few documented exceptions.  */
40475fd0b74Schristos  msp430->op[0] = msp430->op[1];
40575fd0b74Schristos
40675fd0b74Schristos  /* RETI ignores the operand.  */
40775fd0b74Schristos  if (msp430->id == MSO_reti)
40875fd0b74Schristos    msp430->syntax = "%S";
40975fd0b74Schristos
41075fd0b74Schristos  switch (msp430->id)
41175fd0b74Schristos    {
41275fd0b74Schristos    case MSO_rrc:	F_VNZC; break;
41375fd0b74Schristos    case MSO_swpb:	F_____; break;
41475fd0b74Schristos    case MSO_rra:	F_0NZC; break;
41575fd0b74Schristos    case MSO_sxt:	F_0NZC; break;
41675fd0b74Schristos    case MSO_push:	F_____; break;
41775fd0b74Schristos    case MSO_call:	F_____; break;
41875fd0b74Schristos    case MSO_reti:	F_VNZC; break;
41975fd0b74Schristos    default: break;
42075fd0b74Schristos    }
42175fd0b74Schristos
42275fd0b74Schristos  /* 20xx 0010 0000 ---- ----
42375fd0b74Schristos     3cxx 0011 1100 ---- ----
42475fd0b74Schristos          001j mp-- ---- ----.  */
42575fd0b74Schristos/** 001jmp aa addrlsbs		%J	%1				*/
42675fd0b74Schristos
42775fd0b74Schristos  raddr = (aa << 9) | (addrlsbs << 1);
42875fd0b74Schristos  if (raddr & 0x400)
42975fd0b74Schristos    raddr = raddr - 0x800;
43075fd0b74Schristos  /* This is a pc-relative jump, but we don't use SM because that
43175fd0b74Schristos     would load the target address from the memory at X(PC), not use
43275fd0b74Schristos     PC+X *as* the address.  So we use SC to use the address, not the
43375fd0b74Schristos     data at that address.  */
43475fd0b74Schristos  ID (MSO_jmp); SC (pc + raddr + msp430->n_bytes);
43575fd0b74Schristos  msp430->cond = jmp;
43675fd0b74Schristos
43775fd0b74Schristos  /* Extended instructions.  */
43875fd0b74Schristos
43975fd0b74Schristos/** 0000 srcr 0000 dstr		MOVA @%1, %0 */
44075fd0b74Schristos  ID (MSO_mov); SM (srcr, 0); DR (dstr);
44175fd0b74Schristos  msp430->size = 20;
44275fd0b74Schristos  msp430->ofs_430x = 1;
44375fd0b74Schristos
44475fd0b74Schristos/** 0000 srcr 0001 dstr		MOVA @%1+, %0 */
44575fd0b74Schristos  ID (MSO_mov); SI (srcr); DR (dstr);
44675fd0b74Schristos  msp430->size = 20;
44775fd0b74Schristos  msp430->ofs_430x = 1;
44875fd0b74Schristos
44975fd0b74Schristos/** 0000 srcr 0010 dstr		MOVA &%1, %0 */
45075fd0b74Schristos  ID (MSO_mov); SA ((srcr << 16) + IMMU(2)); DR (dstr);
45175fd0b74Schristos  msp430->size = 20;
45275fd0b74Schristos  msp430->ofs_430x = 1;
45375fd0b74Schristos
45475fd0b74Schristos/** 0000 srcr 0011 dstr		MOVA %1, %0 */
45575fd0b74Schristos  ID (MSO_mov); SM (srcr, IMMS(2)); DR (dstr);
45675fd0b74Schristos  msp430->size = 20;
45775fd0b74Schristos  msp430->ofs_430x = 1;
45875fd0b74Schristos
45975fd0b74Schristos/** 0000 srcr 0110 dstr		MOVA %1, &%0 */
46075fd0b74Schristos  ID (MSO_mov); SR (srcr); DA ((dstr << 16) + IMMU(2));
46175fd0b74Schristos  msp430->size = 20;
46275fd0b74Schristos  msp430->ofs_430x = 1;
46375fd0b74Schristos
46475fd0b74Schristos/** 0000 srcr 0111 dstr		MOVA %1, &%0 */
46575fd0b74Schristos  ID (MSO_mov); SR (srcr); DM (dstr, IMMS(2));
46675fd0b74Schristos  msp430->size = 20;
46775fd0b74Schristos  msp430->ofs_430x = 1;
46875fd0b74Schristos
46975fd0b74Schristos/** 0000 srcr 1000 dstr		MOVA %1, %0 */
47075fd0b74Schristos  ID (MSO_mov); SC ((srcr << 16) + IMMU(2)); DR (dstr);
47175fd0b74Schristos  msp430->size = 20;
47275fd0b74Schristos  msp430->ofs_430x = 1;
47375fd0b74Schristos
47475fd0b74Schristos/** 0000 srcr 1001 dstr		CMPA %1, %0 */
47575fd0b74Schristos  ID (MSO_cmp); SC ((srcr << 16) + IMMU(2)); DR (dstr);
47675fd0b74Schristos  msp430->size = 20;
47775fd0b74Schristos  msp430->ofs_430x = 1;
47875fd0b74Schristos  F_VNZC;
47975fd0b74Schristos
48075fd0b74Schristos/** 0000 srcr 1010 dstr		ADDA %1, %0 */
48175fd0b74Schristos  ID (MSO_add); SC ((srcr << 16) + IMMU(2)); DR (dstr);
48275fd0b74Schristos  msp430->size = 20;
48375fd0b74Schristos  msp430->ofs_430x = 1;
48475fd0b74Schristos  F_VNZC;
48575fd0b74Schristos
48675fd0b74Schristos/** 0000 srcr 1011 dstr		SUBA %1, %0 */
48775fd0b74Schristos  ID (MSO_sub); SC ((srcr << 16) + IMMU(2)); DR (dstr);
48875fd0b74Schristos  msp430->size = 20;
48975fd0b74Schristos  msp430->ofs_430x = 1;
49075fd0b74Schristos  F_VNZC;
49175fd0b74Schristos
49275fd0b74Schristos/** 0000 srcr 1011 dstr		SUBA %1, %0 */
49375fd0b74Schristos  ID (MSO_sub); SC ((srcr << 16) + IMMU(2)); DR (dstr);
49475fd0b74Schristos  msp430->size = 20;
49575fd0b74Schristos  msp430->ofs_430x = 1;
49675fd0b74Schristos  F_VNZC;
49775fd0b74Schristos
49875fd0b74Schristos/** 0000 srcr 1100 dstr		MOVA %1, %0 */
49975fd0b74Schristos  ID (MSO_mov); SR (srcr); DR (dstr);
50075fd0b74Schristos  msp430->size = 20;
50175fd0b74Schristos  msp430->ofs_430x = 1;
50275fd0b74Schristos
50375fd0b74Schristos/** 0000 srcr 1101 dstr		CMPA %1, %0 */
50475fd0b74Schristos  ID (MSO_cmp); SR (srcr); DR (dstr);
50575fd0b74Schristos  msp430->size = 20;
50675fd0b74Schristos  msp430->ofs_430x = 1;
50775fd0b74Schristos  F_VNZC;
50875fd0b74Schristos
50975fd0b74Schristos/** 0000 srcr 1110 dstr		ADDA %1, %0 */
51075fd0b74Schristos  ID (MSO_add); SR (srcr); DR (dstr);
51175fd0b74Schristos  msp430->size = 20;
51275fd0b74Schristos  msp430->ofs_430x = 1;
51375fd0b74Schristos  F_VNZC;
51475fd0b74Schristos
51575fd0b74Schristos/** 0000 srcr 1111 dstr		SUBA %1, %0 */
51675fd0b74Schristos  ID (MSO_sub); SR (srcr); DR (dstr);
51775fd0b74Schristos  msp430->size = 20;
51875fd0b74Schristos  msp430->ofs_430x = 1;
51975fd0b74Schristos  F_VNZC;
52075fd0b74Schristos
52175fd0b74Schristos/** 0000 bt00 010w dstr		RRCM.A %c, %0 */
52275fd0b74Schristos  ID (MSO_rrc); DR (dstr); SR (dstr);
52375fd0b74Schristos  msp430->repeats = bt;
52475fd0b74Schristos  msp430->size = w ? 16 : 20;
52575fd0b74Schristos  msp430->ofs_430x = 1;
52675fd0b74Schristos  F_0NZC;
52775fd0b74Schristos
52875fd0b74Schristos/** 0000 bt01 010w dstr		RRAM.A %c, %0 */
52975fd0b74Schristos  ID (MSO_rra); DR (dstr); SR (dstr);
53075fd0b74Schristos  msp430->repeats = bt;
53175fd0b74Schristos  msp430->size = w ? 16 : 20;
53275fd0b74Schristos  msp430->ofs_430x = 1;
53375fd0b74Schristos  F_0NZC;
53475fd0b74Schristos
53575fd0b74Schristos/** 0000 bt10 010w dstr		RLAM.A %c, %0 */
53675fd0b74Schristos  ID (MSO_add); DR (dstr); SR (dstr);
53775fd0b74Schristos  msp430->repeats = bt;
53875fd0b74Schristos  msp430->size = w ? 16 : 20;
53975fd0b74Schristos  msp430->ofs_430x = 1;
54075fd0b74Schristos  F_0NZC;
54175fd0b74Schristos
54275fd0b74Schristos/** 0000 bt11 010w dstr		RRUM.A %c, %0 */
54375fd0b74Schristos  ID (MSO_rru); DR (dstr); SR (dstr);
54475fd0b74Schristos  msp430->repeats = bt;
54575fd0b74Schristos  msp430->size = w ? 16 : 20;
54675fd0b74Schristos  msp430->ofs_430x = 1;
54775fd0b74Schristos  F_0NZC;
54875fd0b74Schristos
54975fd0b74Schristos/** 0001 0011 0000 0000		RETI */
55075fd0b74Schristos  ID (MSO_reti);
55175fd0b74Schristos  msp430->size = 20;
55275fd0b74Schristos  msp430->ofs_430x = 1;
55375fd0b74Schristos
55475fd0b74Schristos/** 0001 0011 01as dstr		CALLA %0 */
55575fd0b74Schristos  ID (MSO_call); AS (dstr, as);
55675fd0b74Schristos  msp430->size = 20;
55775fd0b74Schristos  msp430->ofs_430x = 1;
55875fd0b74Schristos
55975fd0b74Schristos/** 0001 0011 1000 extb		CALLA %0 */
56075fd0b74Schristos  ID (MSO_call); SA (IMMU(2) | (extb << 16));
56175fd0b74Schristos  msp430->size = 20;
56275fd0b74Schristos  msp430->ofs_430x = 1;
56375fd0b74Schristos
56475fd0b74Schristos/** 0001 0011 1001 extb		CALLA %0 */
56575fd0b74Schristos  raddr = IMMU(2) | (extb << 16);
56675fd0b74Schristos  if (raddr & 0x80000)
56775fd0b74Schristos    raddr -= 0x100000;
56875fd0b74Schristos  ID (MSO_call); SA (pc + raddr + msp430->n_bytes);
56975fd0b74Schristos  msp430->size = 20;
57075fd0b74Schristos  msp430->ofs_430x = 1;
57175fd0b74Schristos
57275fd0b74Schristos/** 0001 0011 1011 extb		CALLA %0 */
57375fd0b74Schristos  ID (MSO_call); SC (IMMU(2) | (extb << 16));
57475fd0b74Schristos  msp430->size = 20;
57575fd0b74Schristos  msp430->ofs_430x = 1;
57675fd0b74Schristos
57775fd0b74Schristos/** 0001 010w bits srcr		PUSHM.A %0 */
57875fd0b74Schristos  ID (MSO_push); SR (srcr);
57975fd0b74Schristos  msp430->size = w ? 16 : 20;
58075fd0b74Schristos  msp430->repeats = bits;
58175fd0b74Schristos  msp430->ofs_430x = 1;
58275fd0b74Schristos
58375fd0b74Schristos/** 0001 011w bits dstr		POPM.A %0 */
58475fd0b74Schristos  ID (MSO_pop); DR (dstr);
58575fd0b74Schristos  msp430->size = w ? 16 : 20;
58675fd0b74Schristos  msp430->repeats = bits;
58775fd0b74Schristos  msp430->ofs_430x = 1;
58875fd0b74Schristos
58975fd0b74Schristos/** */
59075fd0b74Schristos
59175fd0b74Schristos  return msp430->n_bytes;
59275fd0b74Schristos}
593