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