* arc-opc.c (MULTSHIFT operand): Delete.
(UNSIGNED, SATURATION): New operands. (mac, mul, mul64, mulu64): New insns. (ext. asl, asr, lsr, ror): Only available on host and graphics cpus. (padc, padd, pmov, pand, psbc, psub, swap): New insns. (host,graphics,audio extended and auxiliary regs): Define. (ss, sc, mh, ml): New suffixes. (arc_opcode_supported, arc_opval_supported): New functions. (insert_multshift, extract_multshift): Deleted.
This commit is contained in:
parent
98d42df90d
commit
ecec4df3e8
@ -1,5 +1,5 @@
|
|||||||
/* Opcode table for the ARC.
|
/* Opcode table for the ARC.
|
||||||
Copyright 1994 Free Software Foundation, Inc.
|
Copyright 1994, 1995 Free Software Foundation, Inc.
|
||||||
Contributed by Doug Evans (dje@cygnus.com).
|
Contributed by Doug Evans (dje@cygnus.com).
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
@ -16,6 +16,9 @@
|
|||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
/* The ARC may eventually be bi-endian.
|
||||||
|
Keep this file byte order independent. */
|
||||||
|
|
||||||
#include "ansidecl.h"
|
#include "ansidecl.h"
|
||||||
#include "opcode/arc.h"
|
#include "opcode/arc.h"
|
||||||
|
|
||||||
@ -43,6 +46,7 @@ INSERT_FN (insert_multshift);
|
|||||||
EXTRACT_FN (extract_reg);
|
EXTRACT_FN (extract_reg);
|
||||||
EXTRACT_FN (extract_flag);
|
EXTRACT_FN (extract_flag);
|
||||||
EXTRACT_FN (extract_cond);
|
EXTRACT_FN (extract_cond);
|
||||||
|
EXTRACT_FN (extract_reladdr);
|
||||||
EXTRACT_FN (extract_unopmacro);
|
EXTRACT_FN (extract_unopmacro);
|
||||||
EXTRACT_FN (extract_multshift);
|
EXTRACT_FN (extract_multshift);
|
||||||
|
|
||||||
@ -69,14 +73,15 @@ EXTRACT_FN (extract_multshift);
|
|||||||
'y' SIZE22 size field in st c,[b,shimm]
|
'y' SIZE22 size field in st c,[b,shimm]
|
||||||
'x' SIGN0 sign extend field ld a,[b,c]
|
'x' SIGN0 sign extend field ld a,[b,c]
|
||||||
'X' SIGN9 sign extend field ld a,[b,shimm]
|
'X' SIGN9 sign extend field ld a,[b,shimm]
|
||||||
'u' ADDRESS3 update field in ld a,[b,c]
|
'w' ADDRESS3 write-back field in ld a,[b,c]
|
||||||
'v' ADDRESS12 update field in ld a,[b,shimm]
|
'W' ADDRESS12 write-back field in ld a,[b,shimm]
|
||||||
'w' ADDRESS24 update field in st c,[b,shimm]
|
'v' ADDRESS24 write-back field in st c,[b,shimm]
|
||||||
'D' CACHEBYPASS5 direct to memory enable (cache bypass) in ld a,[b,c]
|
'D' CACHEBYPASS5 direct to memory enable (cache bypass) in ld a,[b,c]
|
||||||
'e' CACHEBYPASS14 direct to memory enable (cache bypass) in ld a,[b,shimm]
|
'e' CACHEBYPASS14 direct to memory enable (cache bypass) in ld a,[b,shimm]
|
||||||
'E' CACHEBYPASS26 direct to memory enable (cache bypass) in st c,[b,shimm]
|
'E' CACHEBYPASS26 direct to memory enable (cache bypass) in st c,[b,shimm]
|
||||||
|
'u' UNSIGNED unsigned multiply
|
||||||
|
's' SATURATION saturation limit in audio arc mac insn
|
||||||
'U' UNOPMACRO fake operand to copy REGB to REGC for unop macros
|
'U' UNOPMACRO fake operand to copy REGB to REGC for unop macros
|
||||||
'M' MULTSHIFT fake operand to check if target has multiply/shifter
|
|
||||||
|
|
||||||
The following modifiers may appear between the % and char (eg: %.f):
|
The following modifiers may appear between the % and char (eg: %.f):
|
||||||
|
|
||||||
@ -149,7 +154,7 @@ const struct arc_operand arc_operands[] =
|
|||||||
|
|
||||||
/* branch address b, bl, and lp insns */
|
/* branch address b, bl, and lp insns */
|
||||||
#define BRANCH (FORCELIMM + 1)
|
#define BRANCH (FORCELIMM + 1)
|
||||||
{ 'B', 20, 7, ARC_OPERAND_RELATIVE + ARC_OPERAND_SIGNED, insert_reladdr },
|
{ 'B', 20, 7, ARC_OPERAND_RELATIVE + ARC_OPERAND_SIGNED, insert_reladdr, extract_reladdr },
|
||||||
|
|
||||||
/* size field, stored in bit 1,2 */
|
/* size field, stored in bit 1,2 */
|
||||||
#define SIZE1 (BRANCH + 1)
|
#define SIZE1 (BRANCH + 1)
|
||||||
@ -173,39 +178,42 @@ const struct arc_operand arc_operands[] =
|
|||||||
|
|
||||||
/* address write back, stored in bit 3 */
|
/* address write back, stored in bit 3 */
|
||||||
#define ADDRESS3 (SIGN9 + 1)
|
#define ADDRESS3 (SIGN9 + 1)
|
||||||
{ 'u', 1, 3, ARC_OPERAND_SUFFIX },
|
{ 'w', 1, 3, ARC_OPERAND_SUFFIX },
|
||||||
|
|
||||||
/* address write back, stored in bit 12 */
|
/* address write back, stored in bit 12 */
|
||||||
#define ADDRESS12 (ADDRESS3 + 1)
|
#define ADDRESS12 (ADDRESS3 + 1)
|
||||||
{ 'v', 1, 12, ARC_OPERAND_SUFFIX },
|
{ 'W', 1, 12, ARC_OPERAND_SUFFIX },
|
||||||
|
|
||||||
/* address write back, stored in bit 24 */
|
/* address write back, stored in bit 24 */
|
||||||
#define ADDRESS24 (ADDRESS12 + 1)
|
#define ADDRESS24 (ADDRESS12 + 1)
|
||||||
{ 'w', 1, 24, ARC_OPERAND_SUFFIX },
|
{ 'v', 1, 24, ARC_OPERAND_SUFFIX },
|
||||||
|
|
||||||
/* address write back, stored in bit 3 */
|
/* cache bypass, stored in bit 5 */
|
||||||
#define CACHEBYPASS5 (ADDRESS24 + 1)
|
#define CACHEBYPASS5 (ADDRESS24 + 1)
|
||||||
{ 'D', 1, 5, ARC_OPERAND_SUFFIX },
|
{ 'D', 1, 5, ARC_OPERAND_SUFFIX },
|
||||||
|
|
||||||
/* address write back, stored in bit 12 */
|
/* cache bypass, stored in bit 14 */
|
||||||
#define CACHEBYPASS14 (CACHEBYPASS5 + 1)
|
#define CACHEBYPASS14 (CACHEBYPASS5 + 1)
|
||||||
{ 'e', 1, 14, ARC_OPERAND_SUFFIX },
|
{ 'e', 1, 14, ARC_OPERAND_SUFFIX },
|
||||||
|
|
||||||
/* address write back, stored in bit 24 */
|
/* cache bypass, stored in bit 26 */
|
||||||
#define CACHEBYPASS26 (CACHEBYPASS14 + 1)
|
#define CACHEBYPASS26 (CACHEBYPASS14 + 1)
|
||||||
{ 'E', 1, 26, ARC_OPERAND_SUFFIX },
|
{ 'E', 1, 26, ARC_OPERAND_SUFFIX },
|
||||||
|
|
||||||
|
/* unsigned multiply */
|
||||||
|
#define UNSIGNED (CACHEBYPASS26 + 1)
|
||||||
|
{ 'u', 1, 27, ARC_OPERAND_SUFFIX },
|
||||||
|
|
||||||
|
/* unsigned multiply */
|
||||||
|
#define SATURATION (UNSIGNED + 1)
|
||||||
|
{ 's', 1, 28, ARC_OPERAND_SUFFIX },
|
||||||
|
|
||||||
/* unop macro, used to copy REGB to REGC */
|
/* unop macro, used to copy REGB to REGC */
|
||||||
#define UNOPMACRO (CACHEBYPASS26 + 1)
|
#define UNOPMACRO (SATURATION + 1)
|
||||||
{ 'U', 6, ARC_SHIFT_REGC, ARC_OPERAND_FAKE, insert_unopmacro, extract_unopmacro },
|
{ 'U', 6, ARC_SHIFT_REGC, ARC_OPERAND_FAKE, insert_unopmacro, extract_unopmacro },
|
||||||
|
|
||||||
/* multiply/shifter detector */
|
|
||||||
/* ??? Using ARC_OPERAND_FAKE this way is probably taking things too far. */
|
|
||||||
#define MULTSHIFT (UNOPMACRO + 1)
|
|
||||||
{ 'M', 0, 0, ARC_OPERAND_FAKE, insert_multshift, extract_multshift },
|
|
||||||
|
|
||||||
/* '.' modifier ('.' required). */
|
/* '.' modifier ('.' required). */
|
||||||
#define MODDOT (MULTSHIFT + 1)
|
#define MODDOT (UNOPMACRO + 1)
|
||||||
{ '.', 1, 0, ARC_MOD_DOT },
|
{ '.', 1, 0, ARC_MOD_DOT },
|
||||||
|
|
||||||
/* Dummy 'r' modifier for the register table.
|
/* Dummy 'r' modifier for the register table.
|
||||||
@ -255,18 +263,22 @@ unsigned char arc_operand_map[256];
|
|||||||
together. */
|
together. */
|
||||||
|
|
||||||
const struct arc_opcode arc_opcodes[] = {
|
const struct arc_opcode arc_opcodes[] = {
|
||||||
|
{ "mac%u%.s%.q%.f %a,%b,%c%F%S%L", I(-4), I(24), ARC_MACH_AUDIO },
|
||||||
/* Note that "mov" is really an "and". */
|
/* Note that "mov" is really an "and". */
|
||||||
{ "mov%.q%.f %a,%b%F%S%L%U", I(-1), I(12) },
|
{ "mov%.q%.f %a,%b%F%S%L%U", I(-1), I(12) },
|
||||||
{ "mul%M%.q%.f %a,%b,%c%F%S%L", I(-1), I(20) },
|
{ "mul%u%.q%.f %a,%b,%c%F%S%L", I(-2), I(28), ARC_MACH_AUDIO },
|
||||||
{ "mulu%M%.q%.f %a,%b,%c%F%S%L", I(-1), I(21) },
|
/* ??? This insn allows an optional "0," preceding the args. */
|
||||||
|
/* We can't use %u here because it's not a suffix (the "64" is in the way). */
|
||||||
|
{ "mul64%.q%.f %b,%c%F%S%L", I(-1)+A(-1), I(20)+A(-1), ARC_MACH_HOST+ARC_MACH_GRAPHICS },
|
||||||
|
{ "mulu64%.q%.f %b,%c%F%S%L", I(-1)+A(-1), I(21)+A(-1), ARC_MACH_HOST+ARC_MACH_GRAPHICS },
|
||||||
|
|
||||||
{ "adc%.q%.f %a,%b,%c%F%S%L", I(-1), I(9) },
|
{ "adc%.q%.f %a,%b,%c%F%S%L", I(-1), I(9) },
|
||||||
{ "add%.q%.f %a,%b,%c%F%S%L", I(-1), I(8) },
|
{ "add%.q%.f %a,%b,%c%F%S%L", I(-1), I(8) },
|
||||||
{ "and%.q%.f %a,%b,%c%F%S%L", I(-1), I(12) },
|
{ "and%.q%.f %a,%b,%c%F%S%L", I(-1), I(12) },
|
||||||
{ "asl%M%.q%.f %a,%b,%c%F%S%L", I(-1), I(16) },
|
{ "asl%.q%.f %a,%b,%c%F%S%L", I(-1), I(16), ARC_MACH_HOST+ARC_MACH_GRAPHICS },
|
||||||
/* Note that "asl" is really an "add". */
|
/* Note that "asl" is really an "add". */
|
||||||
{ "asl%.q%.f %a,%b%F%S%L%U", I(-1), I(8) },
|
{ "asl%.q%.f %a,%b%F%S%L%U", I(-1), I(8) },
|
||||||
{ "asr%M%.q%.f %a,%b,%c%F%S%L", I(-1), I(18) },
|
{ "asr%.q%.f %a,%b,%c%F%S%L", I(-1), I(18), ARC_MACH_HOST+ARC_MACH_GRAPHICS },
|
||||||
{ "asr%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(1) },
|
{ "asr%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(1) },
|
||||||
{ "bic%.q%.f %a,%b,%c%F%S%L", I(-1), I(14) },
|
{ "bic%.q%.f %a,%b,%c%F%S%L", I(-1), I(14) },
|
||||||
{ "b%q%.n %B", I(-1), I(4) },
|
{ "b%q%.n %B", I(-1), I(4) },
|
||||||
@ -285,14 +297,22 @@ const struct arc_opcode arc_opcodes[] = {
|
|||||||
{ "lr %a,[%Ab]%S%L", I(-1)+C(-1), I(1)+C(0x10) },
|
{ "lr %a,[%Ab]%S%L", I(-1)+C(-1), I(1)+C(0x10) },
|
||||||
/* Note that "lsl" is really an "add". */
|
/* Note that "lsl" is really an "add". */
|
||||||
{ "lsl%.q%.f %a,%b%F%S%L%U", I(-1), I(8) },
|
{ "lsl%.q%.f %a,%b%F%S%L%U", I(-1), I(8) },
|
||||||
{ "lsr%M%.q%.f %a,%b,%c%F%S%L", I(-1), I(17) },
|
{ "lsr%.q%.f %a,%b,%c%F%S%L", I(-1), I(17), ARC_MACH_HOST+ARC_MACH_GRAPHICS },
|
||||||
{ "lsr%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(2) },
|
{ "lsr%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(2) },
|
||||||
/* Note that "nop" is really an "xor". */
|
/* Note that "nop" is really an "xor". */
|
||||||
{ "nop", 0xffffffff, 0x7fffffff },
|
{ "nop", 0xffffffff, 0x7fffffff },
|
||||||
{ "or%.q%.f %a,%b,%c%F%S%L", I(-1), I(13) },
|
{ "or%.q%.f %a,%b,%c%F%S%L", I(-1), I(13) },
|
||||||
|
/* ??? The %a here should be %p or something. */
|
||||||
|
{ "padc%.q%.f %a,%b,%c%F%S%L", I(-1), I(25), ARC_MACH_GRAPHICS },
|
||||||
|
{ "padd%.q%.f %a,%b,%c%F%S%L", I(-1), I(24), ARC_MACH_GRAPHICS },
|
||||||
|
/* Note that "pmov" is really a "pand". */
|
||||||
|
{ "pmov%.q%.f %a,%b%F%S%L%U", I(-1), I(28), ARC_MACH_GRAPHICS },
|
||||||
|
{ "pand%.q%.f %a,%b,%c%F%S%L", I(-1), I(28), ARC_MACH_GRAPHICS },
|
||||||
|
{ "psbc%.q%.f %a,%b,%c%F%S%L", I(-1), I(27), ARC_MACH_GRAPHICS },
|
||||||
|
{ "psub%.q%.f %a,%b,%c%F%S%L", I(-1), I(26), ARC_MACH_GRAPHICS },
|
||||||
/* Note that "rlc" is really an "adc". */
|
/* Note that "rlc" is really an "adc". */
|
||||||
{ "rlc%.q%.f %a,%b%F%S%L%U", I(-1), I(9) },
|
{ "rlc%.q%.f %a,%b%F%S%L%U", I(-1), I(9) },
|
||||||
{ "ror%M%.q%.f %a,%b,%c%F%S%L", I(-1), I(19) },
|
{ "ror%.q%.f %a,%b,%c%F%S%L", I(-1), I(19), ARC_MACH_HOST+ARC_MACH_GRAPHICS },
|
||||||
{ "ror%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(3) },
|
{ "ror%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(3) },
|
||||||
{ "rrc%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(4) },
|
{ "rrc%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(4) },
|
||||||
{ "sbc%.q%.f %a,%b,%c%F%S%L", I(-1), I(11) },
|
{ "sbc%.q%.f %a,%b,%c%F%S%L", I(-1), I(11) },
|
||||||
@ -303,6 +323,7 @@ const struct arc_opcode arc_opcodes[] = {
|
|||||||
{ "st%y%.w%.E %0%c,[%b]%L", I(-1)+R(-1,25,3)+R(-1,21,1)+R(-1,0,511), I(2)+R(0,25,3)+R(0,21,1)+R(0,0,511) },
|
{ "st%y%.w%.E %0%c,[%b]%L", I(-1)+R(-1,25,3)+R(-1,21,1)+R(-1,0,511), I(2)+R(0,25,3)+R(0,21,1)+R(0,0,511) },
|
||||||
{ "st%y%.w%.E %c,[%b,%d]%S%L", I(-1)+R(-1,25,3)+R(-1,21,1), I(2)+R(0,25,3)+R(0,21,1) },
|
{ "st%y%.w%.E %c,[%b,%d]%S%L", I(-1)+R(-1,25,3)+R(-1,21,1), I(2)+R(0,25,3)+R(0,21,1) },
|
||||||
{ "sub%.q%.f %a,%b,%c%F%S%L", I(-1), I(10) },
|
{ "sub%.q%.f %a,%b,%c%F%S%L", I(-1), I(10) },
|
||||||
|
{ "swap%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(9), ARC_MACH_AUDIO },
|
||||||
{ "xor%.q%.f %a,%b,%c%F%S%L", I(-1), I(15) }
|
{ "xor%.q%.f %a,%b,%c%F%S%L", I(-1), I(15) }
|
||||||
};
|
};
|
||||||
int arc_opcodes_count = sizeof (arc_opcodes) / sizeof (arc_opcodes[0]);
|
int arc_opcodes_count = sizeof (arc_opcodes) / sizeof (arc_opcodes[0]);
|
||||||
@ -340,6 +361,76 @@ const struct arc_operand_value arc_reg_names[] =
|
|||||||
{ "lp_end", 3, AUXREG },
|
{ "lp_end", 3, AUXREG },
|
||||||
{ "identity", 4, AUXREG },
|
{ "identity", 4, AUXREG },
|
||||||
{ "debug", 5, AUXREG },
|
{ "debug", 5, AUXREG },
|
||||||
|
|
||||||
|
/* Host ARC Extensions. */
|
||||||
|
{ "mlo", 57, REG, ARC_MACH_HOST },
|
||||||
|
{ "mmid", 58, REG, ARC_MACH_HOST },
|
||||||
|
{ "mhi", 59, REG, ARC_MACH_HOST },
|
||||||
|
{ "ivic", 0x10, AUXREG, ARC_MACH_HOST },
|
||||||
|
{ "ivdc", 0x11, AUXREG, ARC_MACH_HOST },
|
||||||
|
{ "ivdcn", 0x12, AUXREG, ARC_MACH_HOST },
|
||||||
|
{ "flushd", 0x13, AUXREG, ARC_MACH_HOST },
|
||||||
|
{ "saha", 0x14, AUXREG, ARC_MACH_HOST },
|
||||||
|
{ "gahd", 0x15, AUXREG, ARC_MACH_HOST },
|
||||||
|
{ "aahd", 0x16, AUXREG, ARC_MACH_HOST },
|
||||||
|
{ "rrcr", 0x17, AUXREG, ARC_MACH_HOST },
|
||||||
|
{ "rpcr", 0x18, AUXREG, ARC_MACH_HOST },
|
||||||
|
{ "flushdn", 0x19, AUXREG, ARC_MACH_HOST },
|
||||||
|
{ "dbgad1", 0x1a, AUXREG, ARC_MACH_HOST },
|
||||||
|
{ "dbgad2", 0x1b, AUXREG, ARC_MACH_HOST },
|
||||||
|
{ "dbgmde", 0x1c, AUXREG, ARC_MACH_HOST },
|
||||||
|
{ "dbgstat", 0x1d, AUXREG, ARC_MACH_HOST },
|
||||||
|
{ "wag", 0x1e, AUXREG, ARC_MACH_HOST },
|
||||||
|
{ "mulhi", 0x1f, AUXREG, ARC_MACH_HOST },
|
||||||
|
{ "intwide", 0x20, AUXREG, ARC_MACH_HOST },
|
||||||
|
{ "intgen", 0x21, AUXREG, ARC_MACH_HOST },
|
||||||
|
{ "rfsh_n", 0x22, AUXREG, ARC_MACH_HOST },
|
||||||
|
|
||||||
|
/* Graphics ARC Extensions. */
|
||||||
|
{ "mlo", 57, REG, ARC_MACH_GRAPHICS },
|
||||||
|
{ "mmid", 58, REG, ARC_MACH_GRAPHICS },
|
||||||
|
{ "mhi", 59, REG, ARC_MACH_GRAPHICS },
|
||||||
|
{ "ivic", 0x10, AUXREG, ARC_MACH_GRAPHICS },
|
||||||
|
{ "wag", 0x1e, AUXREG, ARC_MACH_GRAPHICS },
|
||||||
|
{ "mulhi", 0x1f, AUXREG, ARC_MACH_GRAPHICS },
|
||||||
|
{ "intwide", 0x20, AUXREG, ARC_MACH_GRAPHICS },
|
||||||
|
{ "intgen", 0x21, AUXREG, ARC_MACH_GRAPHICS },
|
||||||
|
{ "pix", 0x100, AUXREG, ARC_MACH_GRAPHICS },
|
||||||
|
{ "scratch", 0x120, AUXREG, ARC_MACH_GRAPHICS },
|
||||||
|
|
||||||
|
/* Audio ARC Extensions. */
|
||||||
|
{ "macmode", 39, REG, ARC_MACH_AUDIO },
|
||||||
|
{ "rs1", 40, REG, ARC_MACH_AUDIO },
|
||||||
|
{ "rs1n", 41, REG, ARC_MACH_AUDIO },
|
||||||
|
{ "rs1start", 42, REG, ARC_MACH_AUDIO },
|
||||||
|
{ "rs1size", 43, REG, ARC_MACH_AUDIO },
|
||||||
|
{ "rs1delta", 44, REG, ARC_MACH_AUDIO },
|
||||||
|
{ "rs1pos", 45, REG, ARC_MACH_AUDIO },
|
||||||
|
{ "rd1", 46, REG, ARC_MACH_AUDIO },
|
||||||
|
{ "rd1n", 47, REG, ARC_MACH_AUDIO },
|
||||||
|
{ "rd1d", 48, REG, ARC_MACH_AUDIO },
|
||||||
|
{ "rd1pos", 49, REG, ARC_MACH_AUDIO },
|
||||||
|
{ "rs2", 50, REG, ARC_MACH_AUDIO },
|
||||||
|
{ "rs2n", 51, REG, ARC_MACH_AUDIO },
|
||||||
|
{ "rs2start", 52, REG, ARC_MACH_AUDIO },
|
||||||
|
{ "rs2size", 53, REG, ARC_MACH_AUDIO },
|
||||||
|
{ "rs2delta", 54, REG, ARC_MACH_AUDIO },
|
||||||
|
{ "rs2pos", 55, REG, ARC_MACH_AUDIO },
|
||||||
|
{ "rd2", 56, REG, ARC_MACH_AUDIO },
|
||||||
|
{ "rd2n", 57, REG, ARC_MACH_AUDIO },
|
||||||
|
{ "rd2d", 58, REG, ARC_MACH_AUDIO },
|
||||||
|
{ "rd2pos", 59, REG, ARC_MACH_AUDIO },
|
||||||
|
{ "ivic", 0x10, AUXREG, ARC_MACH_AUDIO },
|
||||||
|
{ "wag", 0x1e, AUXREG, ARC_MACH_AUDIO },
|
||||||
|
{ "intwide", 0x20, AUXREG, ARC_MACH_AUDIO },
|
||||||
|
{ "intgen", 0x21, AUXREG, ARC_MACH_AUDIO },
|
||||||
|
{ "bm_sstart", 0x30, AUXREG, ARC_MACH_AUDIO },
|
||||||
|
{ "bm_length", 0x31, AUXREG, ARC_MACH_AUDIO },
|
||||||
|
{ "bm_rstart", 0x32, AUXREG, ARC_MACH_AUDIO },
|
||||||
|
{ "bm_go", 0x33, AUXREG, ARC_MACH_AUDIO },
|
||||||
|
{ "xtp_newval", 0x40, AUXREG, ARC_MACH_AUDIO },
|
||||||
|
{ "sram", 0x400, AUXREG, ARC_MACH_AUDIO },
|
||||||
|
{ "reg_file", 0x800, AUXREG, ARC_MACH_AUDIO },
|
||||||
};
|
};
|
||||||
int arc_reg_names_count = sizeof (arc_reg_names) / sizeof (arc_reg_names[0]);
|
int arc_reg_names_count = sizeof (arc_reg_names) / sizeof (arc_reg_names[0]);
|
||||||
|
|
||||||
@ -399,6 +490,13 @@ const struct arc_operand_value arc_suffixes[] =
|
|||||||
{ "di", 1, CACHEBYPASS5 },
|
{ "di", 1, CACHEBYPASS5 },
|
||||||
{ "di", 1, CACHEBYPASS14 },
|
{ "di", 1, CACHEBYPASS14 },
|
||||||
{ "di", 1, CACHEBYPASS26 },
|
{ "di", 1, CACHEBYPASS26 },
|
||||||
|
|
||||||
|
/* Audio ARC Extensions. */
|
||||||
|
/* ??? The values here are guesses. */
|
||||||
|
{ "ss", 16, COND, ARC_MACH_AUDIO },
|
||||||
|
{ "sc", 17, COND, ARC_MACH_AUDIO },
|
||||||
|
{ "mh", 18, COND, ARC_MACH_AUDIO },
|
||||||
|
{ "ml", 19, COND, ARC_MACH_AUDIO },
|
||||||
};
|
};
|
||||||
int arc_suffixes_count = sizeof (arc_suffixes) / sizeof (arc_suffixes[0]);
|
int arc_suffixes_count = sizeof (arc_suffixes) / sizeof (arc_suffixes[0]);
|
||||||
|
|
||||||
@ -410,20 +508,48 @@ static int cpu_type;
|
|||||||
/* Initialize any tables that need it.
|
/* Initialize any tables that need it.
|
||||||
Must be called once at start up (or when first needed).
|
Must be called once at start up (or when first needed).
|
||||||
|
|
||||||
CPU is a set of bits that say what version of the cpu we have. */
|
FLAGS is a set of bits that say what version of the cpu we have. */
|
||||||
|
|
||||||
void
|
void
|
||||||
arc_opcode_init_tables (cpu)
|
arc_opcode_init_tables (flags)
|
||||||
int cpu;
|
int flags;
|
||||||
{
|
{
|
||||||
register int i,n;
|
register int i,n;
|
||||||
|
|
||||||
|
cpu_type = flags;
|
||||||
|
|
||||||
memset (arc_operand_map, 0, sizeof (arc_operand_map));
|
memset (arc_operand_map, 0, sizeof (arc_operand_map));
|
||||||
n = sizeof (arc_operands) / sizeof (arc_operands[0]);
|
n = sizeof (arc_operands) / sizeof (arc_operands[0]);
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
arc_operand_map[arc_operands[i].fmt] = i;
|
arc_operand_map[arc_operands[i].fmt] = i;
|
||||||
|
}
|
||||||
|
|
||||||
cpu_type = cpu;
|
/* Return non-zero if OPCODE is supported on the specified cpu.
|
||||||
|
Cpu selection is made when calling `arc_opcode_init_tables'. */
|
||||||
|
|
||||||
|
int
|
||||||
|
arc_opcode_supported (opcode)
|
||||||
|
const struct arc_opcode *opcode;
|
||||||
|
{
|
||||||
|
if (ARC_OPCODE_MACH (opcode->flags) == 0)
|
||||||
|
return 1;
|
||||||
|
if (ARC_OPCODE_MACH (opcode->flags) & ARC_HAVE_MACH (cpu_type))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return non-zero if OPVAL is supported on the specified cpu.
|
||||||
|
Cpu selection is made when calling `arc_opcode_init_tables'. */
|
||||||
|
|
||||||
|
int
|
||||||
|
arc_opval_supported (opval)
|
||||||
|
const struct arc_operand_value *opval;
|
||||||
|
{
|
||||||
|
if (ARC_OPVAL_MACH (opval->flags) == 0)
|
||||||
|
return 1;
|
||||||
|
if (ARC_OPVAL_MACH (opval->flags) & ARC_HAVE_MACH (cpu_type))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nonzero if we've seen an 'f' suffix (in certain insns). */
|
/* Nonzero if we've seen an 'f' suffix (in certain insns). */
|
||||||
@ -725,25 +851,9 @@ insert_reladdr (insn, operand, mods, reg, value, errmsg)
|
|||||||
long value;
|
long value;
|
||||||
const char **errmsg;
|
const char **errmsg;
|
||||||
{
|
{
|
||||||
/* FIXME: Addresses are stored * 4. Do we want to handle that here? */
|
if (value & 3)
|
||||||
insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
|
*errmsg = "branch address not on 4 byte boundary";
|
||||||
return insn;
|
insn |= ((value >> 2) & ((1 << operand->bits) - 1)) << operand->shift;
|
||||||
}
|
|
||||||
|
|
||||||
/* Fake operand to disallow the multiply and variable shift insns if the cpu
|
|
||||||
doesn't have them. */
|
|
||||||
|
|
||||||
static arc_insn
|
|
||||||
insert_multshift (insn, operand, mods, reg, value, errmsg)
|
|
||||||
arc_insn insn;
|
|
||||||
const struct arc_operand *operand;
|
|
||||||
int mods;
|
|
||||||
const struct arc_operand_value *reg;
|
|
||||||
long value;
|
|
||||||
const char **errmsg;
|
|
||||||
{
|
|
||||||
if (!(cpu_type & ARC_HAVE_MULT_SHIFT))
|
|
||||||
*errmsg = "cpu doesn't support this insn";
|
|
||||||
return insn;
|
return insn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -897,6 +1007,27 @@ extract_cond (insn, operand, mods, opval, invalid)
|
|||||||
return cond;
|
return cond;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Extract a branch address.
|
||||||
|
We return the value as a real address (not right shifted by 2). */
|
||||||
|
|
||||||
|
static long
|
||||||
|
extract_reladdr (insn, operand, mods, opval, invalid)
|
||||||
|
arc_insn *insn;
|
||||||
|
const struct arc_operand *operand;
|
||||||
|
int mods;
|
||||||
|
const struct arc_operand_value **opval;
|
||||||
|
int *invalid;
|
||||||
|
{
|
||||||
|
long addr;
|
||||||
|
|
||||||
|
addr = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1);
|
||||||
|
if ((operand->flags & ARC_OPERAND_SIGNED)
|
||||||
|
&& (addr & (1 << (operand->bits - 1))))
|
||||||
|
addr -= 1 << operand->bits;
|
||||||
|
|
||||||
|
return addr << 2;
|
||||||
|
}
|
||||||
|
|
||||||
/* The only thing this does is set the `invalid' flag if B != C.
|
/* The only thing this does is set the `invalid' flag if B != C.
|
||||||
This is needed because the "mov" macro appears before it's real insn "and"
|
This is needed because the "mov" macro appears before it's real insn "and"
|
||||||
and we don't want the disassembler to confuse them. */
|
and we don't want the disassembler to confuse them. */
|
||||||
@ -920,22 +1051,6 @@ extract_unopmacro (insn, operand, mods, opval, invalid)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't recognize the multiply and variable shift insns if the cpu doesn't
|
|
||||||
have them.
|
|
||||||
|
|
||||||
??? Actually, we probably should anyway. */
|
|
||||||
|
|
||||||
static long
|
|
||||||
extract_multshift (insn, operand, mods, opval, invalid)
|
|
||||||
arc_insn *insn;
|
|
||||||
const struct arc_operand *operand;
|
|
||||||
int mods;
|
|
||||||
const struct arc_operand_value **opval;
|
|
||||||
int *invalid;
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Utility for the extraction functions to return the index into
|
/* Utility for the extraction functions to return the index into
|
||||||
`arc_suffixes'. */
|
`arc_suffixes'. */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user