* config/tc-mips.c (mips_set_options): Add ase_dsp for DSP instructions.
(mips_opts): Add -1 to initialize ase_dsp. (file_ase_dsp): New variable for -mdsp. (CPU_HAS_DSP): New define. (validate_mips_insn): Add supports for 3, 4, 5, 6, 7, 8, 9, 0, ', :, @ operand formats. (mips_ip): Add min_range and max_range for checking singed numbers. Check ase_dsp to enable DSP instructions. Handle 3, 4, 5, 6, 7, 8, 9, 0, ', :, @ operand formats. (OPTION_DSP, OPTION_NO_DSP): New define. (OPTION_COMPAT_ARCH_BASE): Change because of inserting DSP define. (md_parse_option): Parse OPTION_DSP and OPTION_NO_DSP. (mips_after_parse_args): Set ase_dsp based on CPU. (s_mipsset): Handle ".set dsp" and ".set nodsp". (mips_elf_final_processing): Remind of adding new flag for DSP ASE. (md_show_usage): Show usage of -mdsp and -mno-dsp.
This commit is contained in:
parent
fd25c5a9db
commit
74cd071d38
|
@ -1,3 +1,22 @@
|
|||
2005-08-25 Chao-ying Fu <fu@mips.com>
|
||||
|
||||
* config/tc-mips.c (mips_set_options): Add ase_dsp for DSP instructions.
|
||||
(mips_opts): Add -1 to initialize ase_dsp.
|
||||
(file_ase_dsp): New variable for -mdsp.
|
||||
(CPU_HAS_DSP): New define.
|
||||
(validate_mips_insn): Add supports for 3, 4, 5, 6, 7, 8, 9, 0, ', :, @
|
||||
operand formats.
|
||||
(mips_ip): Add min_range and max_range for checking singed numbers.
|
||||
Check ase_dsp to enable DSP instructions.
|
||||
Handle 3, 4, 5, 6, 7, 8, 9, 0, ', :, @ operand formats.
|
||||
(OPTION_DSP, OPTION_NO_DSP): New define.
|
||||
(OPTION_COMPAT_ARCH_BASE): Change because of inserting DSP define.
|
||||
(md_parse_option): Parse OPTION_DSP and OPTION_NO_DSP.
|
||||
(mips_after_parse_args): Set ase_dsp based on CPU.
|
||||
(s_mipsset): Handle ".set dsp" and ".set nodsp".
|
||||
(mips_elf_final_processing): Remind of adding new flag for DSP ASE.
|
||||
(md_show_usage): Show usage of -mdsp and -mno-dsp.
|
||||
|
||||
2005-08-23 David Ung <davidu@mips.com>
|
||||
|
||||
* config/tc-mips.c (mips_cpu_info_table): Add 5kf to the table of
|
||||
|
|
|
@ -193,6 +193,7 @@ struct mips_set_options
|
|||
command line options, and based on the default architecture. */
|
||||
int ase_mips3d;
|
||||
int ase_mdmx;
|
||||
int ase_dsp;
|
||||
/* Whether we are assembling for the mips16 processor. 0 if we are
|
||||
not, 1 if we are, and -1 if the value has not been initialized.
|
||||
Changed by `.set mips16' and `.set nomips16', and the -mips16 and
|
||||
|
@ -243,7 +244,7 @@ static int file_mips_fp32 = -1;
|
|||
|
||||
static struct mips_set_options mips_opts =
|
||||
{
|
||||
ISA_UNKNOWN, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, CPU_UNKNOWN, FALSE
|
||||
ISA_UNKNOWN, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, CPU_UNKNOWN, FALSE
|
||||
};
|
||||
|
||||
/* These variables are filled in with the masks of registers used.
|
||||
|
@ -267,6 +268,10 @@ static int file_ase_mips3d;
|
|||
command line (e.g., by -march). */
|
||||
static int file_ase_mdmx;
|
||||
|
||||
/* True if -mdsp was passed or implied by arguments passed on the
|
||||
command line (e.g., by -march). */
|
||||
static int file_ase_dsp;
|
||||
|
||||
/* The argument of the -march= flag. The architecture we are assembling. */
|
||||
static int file_mips_arch = CPU_UNKNOWN;
|
||||
static const char *mips_arch_string;
|
||||
|
@ -365,6 +370,10 @@ static int mips_32bitmode = 0;
|
|||
#define CPU_HAS_MDMX(cpu) (FALSE \
|
||||
)
|
||||
|
||||
/* Return true if the given CPU supports the DSP ASE. */
|
||||
#define CPU_HAS_DSP(cpu) (FALSE \
|
||||
)
|
||||
|
||||
/* True if CPU has a dror instruction. */
|
||||
#define CPU_HAS_DROR(CPU) ((CPU) == CPU_VR5400 || (CPU) == CPU_VR5500)
|
||||
|
||||
|
@ -7817,6 +7826,17 @@ validate_mips_insn (const struct mips_opcode *opc)
|
|||
case '%': USE_BITS (OP_MASK_VECALIGN, OP_SH_VECALIGN); break;
|
||||
case '[': break;
|
||||
case ']': break;
|
||||
case '3': USE_BITS (OP_MASK_SA3, OP_SH_SA3); break;
|
||||
case '4': USE_BITS (OP_MASK_SA4, OP_SH_SA4); break;
|
||||
case '5': USE_BITS (OP_MASK_IMM8, OP_SH_IMM8); break;
|
||||
case '6': USE_BITS (OP_MASK_RS, OP_SH_RS); break;
|
||||
case '7': USE_BITS (OP_MASK_DSPACC, OP_SH_DSPACC); break;
|
||||
case '8': USE_BITS (OP_MASK_WRDSP, OP_SH_WRDSP); break;
|
||||
case '9': USE_BITS (OP_MASK_DSPACC_S, OP_SH_DSPACC_S);break;
|
||||
case '0': USE_BITS (OP_MASK_DSPSFT, OP_SH_DSPSFT); break;
|
||||
case '\'': USE_BITS (OP_MASK_RDDSP, OP_SH_RDDSP); break;
|
||||
case ':': USE_BITS (OP_MASK_DSPSFT_7, OP_SH_DSPSFT_7);break;
|
||||
case '@': USE_BITS (OP_MASK_IMM10, OP_SH_IMM10); break;
|
||||
default:
|
||||
as_bad (_("internal: bad mips opcode (unknown operand type `%c'): %s %s"),
|
||||
c, opc->name, opc->args);
|
||||
|
@ -7851,6 +7871,7 @@ mips_ip (char *str, struct mips_cl_insn *ip)
|
|||
unsigned int limlo, limhi;
|
||||
char *s_reset;
|
||||
char save_c = 0;
|
||||
offsetT min_range, max_range;
|
||||
|
||||
insn_error = NULL;
|
||||
|
||||
|
@ -7913,6 +7934,7 @@ mips_ip (char *str, struct mips_cl_insn *ip)
|
|||
(mips_opts.isa
|
||||
| (file_ase_mips16 ? INSN_MIPS16 : 0)
|
||||
| (mips_opts.ase_mdmx ? INSN_MDMX : 0)
|
||||
| (mips_opts.ase_dsp ? INSN_DSP : 0)
|
||||
| (mips_opts.ase_mips3d ? INSN_MIPS3D : 0)),
|
||||
mips_opts.arch))
|
||||
ok = TRUE;
|
||||
|
@ -7965,6 +7987,175 @@ mips_ip (char *str, struct mips_cl_insn *ip)
|
|||
return;
|
||||
break;
|
||||
|
||||
case '3': /* dsp 3-bit unsigned immediate in bit 21 */
|
||||
my_getExpression (&imm_expr, s);
|
||||
check_absolute_expr (ip, &imm_expr);
|
||||
if (imm_expr.X_add_number & ~OP_MASK_SA3)
|
||||
{
|
||||
as_warn (_("DSP immediate not in range 0..%d (%lu)"),
|
||||
OP_MASK_SA3, (unsigned long) imm_expr.X_add_number);
|
||||
imm_expr.X_add_number &= OP_MASK_SA3;
|
||||
}
|
||||
ip->insn_opcode |= imm_expr.X_add_number << OP_SH_SA3;
|
||||
imm_expr.X_op = O_absent;
|
||||
s = expr_end;
|
||||
continue;
|
||||
|
||||
case '4': /* dsp 4-bit unsigned immediate in bit 21 */
|
||||
my_getExpression (&imm_expr, s);
|
||||
check_absolute_expr (ip, &imm_expr);
|
||||
if (imm_expr.X_add_number & ~OP_MASK_SA4)
|
||||
{
|
||||
as_warn (_("DSP immediate not in range 0..%d (%lu)"),
|
||||
OP_MASK_SA4, (unsigned long) imm_expr.X_add_number);
|
||||
imm_expr.X_add_number &= OP_MASK_SA4;
|
||||
}
|
||||
ip->insn_opcode |= imm_expr.X_add_number << OP_SH_SA4;
|
||||
imm_expr.X_op = O_absent;
|
||||
s = expr_end;
|
||||
continue;
|
||||
|
||||
case '5': /* dsp 8-bit unsigned immediate in bit 16 */
|
||||
my_getExpression (&imm_expr, s);
|
||||
check_absolute_expr (ip, &imm_expr);
|
||||
if (imm_expr.X_add_number & ~OP_MASK_IMM8)
|
||||
{
|
||||
as_warn (_("DSP immediate not in range 0..%d (%lu)"),
|
||||
OP_MASK_IMM8, (unsigned long) imm_expr.X_add_number);
|
||||
imm_expr.X_add_number &= OP_MASK_IMM8;
|
||||
}
|
||||
ip->insn_opcode |= imm_expr.X_add_number << OP_SH_IMM8;
|
||||
imm_expr.X_op = O_absent;
|
||||
s = expr_end;
|
||||
continue;
|
||||
|
||||
case '6': /* dsp 5-bit unsigned immediate in bit 21 */
|
||||
my_getExpression (&imm_expr, s);
|
||||
check_absolute_expr (ip, &imm_expr);
|
||||
if (imm_expr.X_add_number & ~OP_MASK_RS)
|
||||
{
|
||||
as_warn (_("DSP immediate not in range 0..%d (%lu)"),
|
||||
OP_MASK_RS, (unsigned long) imm_expr.X_add_number);
|
||||
imm_expr.X_add_number &= OP_MASK_RS;
|
||||
}
|
||||
ip->insn_opcode |= imm_expr.X_add_number << OP_SH_RS;
|
||||
imm_expr.X_op = O_absent;
|
||||
s = expr_end;
|
||||
continue;
|
||||
|
||||
case '7': /* four dsp accumulators in bits 11,12 */
|
||||
if (s[0] == '$' && s[1] == 'a' && s[2] == 'c' &&
|
||||
s[3] >= '0' && s[3] <= '3')
|
||||
{
|
||||
regno = s[3] - '0';
|
||||
s += 4;
|
||||
ip->insn_opcode |= regno << OP_SH_DSPACC;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
as_bad (_("Invalid dsp acc register"));
|
||||
break;
|
||||
|
||||
case '8': /* dsp 6-bit unsigned immediate in bit 11 */
|
||||
my_getExpression (&imm_expr, s);
|
||||
check_absolute_expr (ip, &imm_expr);
|
||||
if (imm_expr.X_add_number & ~OP_MASK_WRDSP)
|
||||
{
|
||||
as_warn (_("DSP immediate not in range 0..%d (%lu)"),
|
||||
OP_MASK_WRDSP,
|
||||
(unsigned long) imm_expr.X_add_number);
|
||||
imm_expr.X_add_number &= OP_MASK_WRDSP;
|
||||
}
|
||||
ip->insn_opcode |= imm_expr.X_add_number << OP_SH_WRDSP;
|
||||
imm_expr.X_op = O_absent;
|
||||
s = expr_end;
|
||||
continue;
|
||||
|
||||
case '9': /* four dsp accumulators in bits 21,22 */
|
||||
if (s[0] == '$' && s[1] == 'a' && s[2] == 'c' &&
|
||||
s[3] >= '0' && s[3] <= '3')
|
||||
{
|
||||
regno = s[3] - '0';
|
||||
s += 4;
|
||||
ip->insn_opcode |= regno << OP_SH_DSPACC_S;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
as_bad (_("Invalid dsp acc register"));
|
||||
break;
|
||||
|
||||
case '0': /* dsp 6-bit signed immediate in bit 20 */
|
||||
my_getExpression (&imm_expr, s);
|
||||
check_absolute_expr (ip, &imm_expr);
|
||||
min_range = -((OP_MASK_DSPSFT + 1) >> 1);
|
||||
max_range = ((OP_MASK_DSPSFT + 1) >> 1) - 1;
|
||||
if (imm_expr.X_add_number < min_range ||
|
||||
imm_expr.X_add_number > max_range)
|
||||
{
|
||||
as_warn (_("DSP immediate not in range %ld..%ld (%ld)"),
|
||||
(long) min_range, (long) max_range,
|
||||
(long) imm_expr.X_add_number);
|
||||
}
|
||||
imm_expr.X_add_number &= OP_MASK_DSPSFT;
|
||||
ip->insn_opcode |= ((unsigned long) imm_expr.X_add_number
|
||||
<< OP_SH_DSPSFT);
|
||||
imm_expr.X_op = O_absent;
|
||||
s = expr_end;
|
||||
continue;
|
||||
|
||||
case '\'': /* dsp 6-bit unsigned immediate in bit 16 */
|
||||
my_getExpression (&imm_expr, s);
|
||||
check_absolute_expr (ip, &imm_expr);
|
||||
if (imm_expr.X_add_number & ~OP_MASK_RDDSP)
|
||||
{
|
||||
as_warn (_("DSP immediate not in range 0..%d (%lu)"),
|
||||
OP_MASK_RDDSP,
|
||||
(unsigned long) imm_expr.X_add_number);
|
||||
imm_expr.X_add_number &= OP_MASK_RDDSP;
|
||||
}
|
||||
ip->insn_opcode |= imm_expr.X_add_number << OP_SH_RDDSP;
|
||||
imm_expr.X_op = O_absent;
|
||||
s = expr_end;
|
||||
continue;
|
||||
|
||||
case ':': /* dsp 7-bit signed immediate in bit 19 */
|
||||
my_getExpression (&imm_expr, s);
|
||||
check_absolute_expr (ip, &imm_expr);
|
||||
min_range = -((OP_MASK_DSPSFT_7 + 1) >> 1);
|
||||
max_range = ((OP_MASK_DSPSFT_7 + 1) >> 1) - 1;
|
||||
if (imm_expr.X_add_number < min_range ||
|
||||
imm_expr.X_add_number > max_range)
|
||||
{
|
||||
as_warn (_("DSP immediate not in range %ld..%ld (%ld)"),
|
||||
(long) min_range, (long) max_range,
|
||||
(long) imm_expr.X_add_number);
|
||||
}
|
||||
imm_expr.X_add_number &= OP_MASK_DSPSFT_7;
|
||||
ip->insn_opcode |= ((unsigned long) imm_expr.X_add_number
|
||||
<< OP_SH_DSPSFT_7);
|
||||
imm_expr.X_op = O_absent;
|
||||
s = expr_end;
|
||||
continue;
|
||||
|
||||
case '@': /* dsp 10-bit signed immediate in bit 16 */
|
||||
my_getExpression (&imm_expr, s);
|
||||
check_absolute_expr (ip, &imm_expr);
|
||||
min_range = -((OP_MASK_IMM10 + 1) >> 1);
|
||||
max_range = ((OP_MASK_IMM10 + 1) >> 1) - 1;
|
||||
if (imm_expr.X_add_number < min_range ||
|
||||
imm_expr.X_add_number > max_range)
|
||||
{
|
||||
as_warn (_("DSP immediate not in range %ld..%ld (%ld)"),
|
||||
(long) min_range, (long) max_range,
|
||||
(long) imm_expr.X_add_number);
|
||||
}
|
||||
imm_expr.X_add_number &= OP_MASK_IMM10;
|
||||
ip->insn_opcode |= ((unsigned long) imm_expr.X_add_number
|
||||
<< OP_SH_IMM10);
|
||||
imm_expr.X_op = O_absent;
|
||||
s = expr_end;
|
||||
continue;
|
||||
|
||||
case ',':
|
||||
if (*s++ == *args)
|
||||
continue;
|
||||
|
@ -10027,9 +10218,13 @@ struct option md_longopts[] =
|
|||
{"mdmx", no_argument, NULL, OPTION_MDMX},
|
||||
#define OPTION_NO_MDMX (OPTION_ASE_BASE + 5)
|
||||
{"no-mdmx", no_argument, NULL, OPTION_NO_MDMX},
|
||||
#define OPTION_DSP (OPTION_ASE_BASE + 6)
|
||||
{"mdsp", no_argument, NULL, OPTION_DSP},
|
||||
#define OPTION_NO_DSP (OPTION_ASE_BASE + 7)
|
||||
{"mno-dsp", no_argument, NULL, OPTION_NO_DSP},
|
||||
|
||||
/* Old-style architecture options. Don't add more of these. */
|
||||
#define OPTION_COMPAT_ARCH_BASE (OPTION_ASE_BASE + 6)
|
||||
#define OPTION_COMPAT_ARCH_BASE (OPTION_ASE_BASE + 8)
|
||||
#define OPTION_M4650 (OPTION_COMPAT_ARCH_BASE + 0)
|
||||
{"m4650", no_argument, NULL, OPTION_M4650},
|
||||
#define OPTION_NO_M4650 (OPTION_COMPAT_ARCH_BASE + 1)
|
||||
|
@ -10281,6 +10476,14 @@ md_parse_option (int c, char *arg)
|
|||
mips_opts.ase_mdmx = 0;
|
||||
break;
|
||||
|
||||
case OPTION_DSP:
|
||||
mips_opts.ase_dsp = 1;
|
||||
break;
|
||||
|
||||
case OPTION_NO_DSP:
|
||||
mips_opts.ase_dsp = 0;
|
||||
break;
|
||||
|
||||
case OPTION_MIPS16:
|
||||
mips_opts.mips16 = 1;
|
||||
mips_no_prev_insn ();
|
||||
|
@ -10635,11 +10838,14 @@ mips_after_parse_args (void)
|
|||
mips_opts.ase_mips3d = (CPU_HAS_MIPS3D (file_mips_arch)) ? 1 : 0;
|
||||
if (mips_opts.ase_mdmx == -1)
|
||||
mips_opts.ase_mdmx = (CPU_HAS_MDMX (file_mips_arch)) ? 1 : 0;
|
||||
if (mips_opts.ase_dsp == -1)
|
||||
mips_opts.ase_dsp = (CPU_HAS_DSP (file_mips_arch)) ? 1 : 0;
|
||||
|
||||
file_mips_isa = mips_opts.isa;
|
||||
file_ase_mips16 = mips_opts.mips16;
|
||||
file_ase_mips3d = mips_opts.ase_mips3d;
|
||||
file_ase_mdmx = mips_opts.ase_mdmx;
|
||||
file_ase_dsp = mips_opts.ase_dsp;
|
||||
mips_opts.gp32 = file_mips_gp32;
|
||||
mips_opts.fp32 = file_mips_fp32;
|
||||
|
||||
|
@ -11577,6 +11783,10 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
|
|||
mips_opts.ase_mdmx = 1;
|
||||
else if (strcmp (name, "nomdmx") == 0)
|
||||
mips_opts.ase_mdmx = 0;
|
||||
else if (strcmp (name, "dsp") == 0)
|
||||
mips_opts.ase_dsp = 1;
|
||||
else if (strcmp (name, "nodsp") == 0)
|
||||
mips_opts.ase_dsp = 0;
|
||||
else if (strncmp (name, "mips", 4) == 0 || strncmp (name, "arch=", 5) == 0)
|
||||
{
|
||||
int reset = 0;
|
||||
|
@ -13311,6 +13521,8 @@ mips_elf_final_processing (void)
|
|||
elf_elfheader (stdoutput)->e_flags |= EF_MIPS_CPIC;
|
||||
|
||||
/* Set MIPS ELF flags for ASEs. */
|
||||
/* We may need to define a new flag for DSP ASE, and set this flag when
|
||||
file_ase_dsp is true. */
|
||||
if (file_ase_mips16)
|
||||
elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ARCH_ASE_M16;
|
||||
#if 0 /* XXX FIXME */
|
||||
|
@ -14015,6 +14227,9 @@ MIPS options:\n\
|
|||
-mips16 generate mips16 instructions\n\
|
||||
-no-mips16 do not generate mips16 instructions\n"));
|
||||
fprintf (stream, _("\
|
||||
-mdsp generate DSP instructions\n\
|
||||
-mno-dsp do not generate DSP instructions\n"));
|
||||
fprintf (stream, _("\
|
||||
-mfix-vr4120 work around certain VR4120 errata\n\
|
||||
-mfix-vr4130 work around VR4130 mflo/mfhi errata\n\
|
||||
-mgp32 use 32-bit GPRs, regardless of the chosen ISA\n\
|
||||
|
|
Loading…
Reference in New Issue