* Bringing over sky (dvp) gas change from branch.

Wed Jul 22 17:39:28 1998  Frank Ch. Eigler  <fche@cygnus.com>
        * config/tc-dvp.c (parse_float): Accept 0xhex constants
        also for VU LOI operand.
This commit is contained in:
Frank Ch. Eigler 1998-07-22 18:38:27 +00:00
parent 1ca268445f
commit e4d7741205
2 changed files with 107 additions and 70 deletions

View file

@ -1,3 +1,10 @@
start-sanitize-sky
Wed Jul 22 17:39:28 1998 Frank Ch. Eigler <fche@cygnus.com>
* config/tc-dvp.c (parse_float): Accept 0xhex constants
also for VU LOI operand.
end-sanitize-sky
Wed Jul 22 14:36:56 1998 Ian Lance Taylor <ian@cygnus.com>
* doc/as.texinfo: Add documentation for .end, .exitm, .fail,

View file

@ -103,8 +103,9 @@ const char FLT_CHARS[] = "dD";
Allowed state transitions:
ASM_INIT <--> ASM_MPG
ASM_DIRECT <--> ASM_GIF
ASM_UNPACK
ASM_UNPACK <--> ASM_GIF
ASM_VU
ASM_GIF
FIXME: Make the ASM_INIT -> ASM_VU a one way transition.
".vu" must be seen at the top of the file,
@ -112,7 +113,7 @@ const char FLT_CHARS[] = "dD";
*/
typedef enum {
ASM_INIT, ASM_DIRECT, ASM_MPG, ASM_UNPACK, ASM_VU, ASM_GIF
ASM_INIT, ASM_DIRECT, ASM_MPG, ASM_UNPACK, ASM_VU, ASM_GIF, ASM_MAX
} asm_state;
/* We need to maintain a stack of the current and previous status to handle
@ -120,14 +121,14 @@ typedef enum {
#define MAX_STATE_DEPTH 2
static asm_state asm_state_stack[MAX_STATE_DEPTH];
/* Current state's index in the stack. */
static int cur_state_index;
static int cur_state_level;
/* Macro to fetch the current state. */
#define CUR_ASM_STATE (asm_state_stack[cur_state_index])
#define CUR_ASM_STATE (asm_state_stack[cur_state_level])
/* Functions to push/pop the state stack. */
static void push_asm_state PARAMS ((asm_state));
static void pop_asm_state PARAMS ((int));
static void set_asm_state PARAMS ((asm_state));
static void set_asm_state PARAMS ((asm_state, const char *));
/* Set to non-zero if any non-vu insn seen.
Used to control type of relocations emitted. */
@ -275,7 +276,7 @@ static void s_enddirect PARAMS ((int));
static void s_endmpg PARAMS ((int));
static void s_endunpack PARAMS ((int));
static void s_endgif PARAMS ((int));
static void s_state PARAMS ((int));
static void s_vu PARAMS ((int));
static void s_dvp_func PARAMS ((int));
/* The target specific pseudo-ops which we support. */
@ -290,7 +291,7 @@ const pseudo_typeS md_pseudo_table[] =
{ "endmpg", s_endmpg, ENDMPG_USER },
{ "endunpack", s_endunpack, 0 },
{ "endgif", s_endgif, 0 },
{ "vu", s_state, ASM_VU },
{ "vu", s_vu, 0 },
/* We need to intercept .func/.endfunc so that we can prepend _$.
??? Not sure this is right though as _$foo is the lma version. */
{ "func", s_dvp_func, 0 },
@ -309,8 +310,7 @@ md_begin ()
force_mach_label ();
/* Initialize the parsing state. */
cur_state_index = 0;
set_asm_state (ASM_INIT);
set_asm_state (ASM_INIT, NULL);
/* Pack vif insns in dma tags by default. */
dma_pack_vif_p = 1;
@ -402,21 +402,8 @@ md_assemble (str)
{
as_bad ("missing .endgif");
pop_asm_state (1);
/* We still parse the instruction. */
}
/* Ditto for unpack. */
if (CUR_ASM_STATE == ASM_UNPACK)
{
as_bad ("missing .endunpack");
pop_asm_state (1);
}
#if 0 /* this doesn't work of course as gif insns may follow */
/* Ditto for direct. */
if (CUR_ASM_STATE == ASM_DIRECT)
{
as_bad ("missing .enddirect");
pop_asm_state (1);
}
#endif
if (CUR_ASM_STATE == ASM_INIT)
{
@ -428,7 +415,8 @@ md_assemble (str)
assemble_vif (str);
non_vu_insn_seen_p = 1;
}
else if (CUR_ASM_STATE == ASM_DIRECT)
else if (CUR_ASM_STATE == ASM_DIRECT
|| CUR_ASM_STATE == ASM_UNPACK)
{
assemble_gif (str);
non_vu_insn_seen_p = 1;
@ -823,21 +811,21 @@ assemble_vif (str)
if (opcode->flags & VIF_OPCODE_MPG)
{
record_mach (DVP_VUUP, 1);
set_asm_state (ASM_MPG);
set_asm_state (ASM_MPG, "mpg");
byte_len = insert_file (file, insert_mpg_marker, 0, 256 * 8);
s_endmpg (ENDMPG_INTERNAL);
}
else if (opcode->flags & VIF_OPCODE_DIRECT)
{
record_mach (DVP_GIF, 1);
set_asm_state (ASM_DIRECT);
set_asm_state (ASM_DIRECT, "direct");
byte_len = insert_file (file, NULL, 0, 0);
s_enddirect (1);
}
else if (opcode->flags & VIF_OPCODE_UNPACK)
{
int max_len = 0; /*unpack_max_byte_len (insn_buf[0]);*/
set_asm_state (ASM_UNPACK);
set_asm_state (ASM_UNPACK, "unpack");
byte_len = insert_file (file, NULL /*insert_unpack_marker*/,
insn_buf[0], max_len);
s_endunpack (1);
@ -857,19 +845,20 @@ assemble_vif (str)
if (opcode->flags & VIF_OPCODE_MPG)
{
set_asm_state (ASM_MPG);
set_asm_state (ASM_MPG, "mpg");
/* Enable automatic mpg insertion every 256 insns. */
vu_count = 0;
}
else if (opcode->flags & VIF_OPCODE_DIRECT)
set_asm_state (ASM_DIRECT);
set_asm_state (ASM_DIRECT, "direct");
else if (opcode->flags & VIF_OPCODE_UNPACK)
set_asm_state (ASM_UNPACK);
set_asm_state (ASM_UNPACK, "unpack");
}
}
}
/* Subroutine of md_assemble to assemble GIF instructions. */
/* Subroutine of md_assemble to assemble GIF instructions.
We assume CUR_ASM_STATE is one of ASM_{INIT,DIRECT,UNPACK}. */
static void
assemble_gif (str)
@ -1427,41 +1416,50 @@ force_mach_label ()
return 1;
}
/* Push/pop the current parsing state. */
/* Push the current parsing state to NEW_STATE. */
static void
push_asm_state (new_state)
asm_state new_state;
{
++cur_state_index;
if (cur_state_index == MAX_STATE_DEPTH)
asm_state cur_state = CUR_ASM_STATE;
++cur_state_level;
if (cur_state_level == MAX_STATE_DEPTH)
as_fatal ("internal error: unexpected state push");
asm_state_stack[cur_state_index] = new_state;
asm_state_stack[cur_state_level] = new_state;
}
/* TOP_OK_P is non-zero if it's ok that we're at the top of the stack.
This happens if there are errors in the assembler code.
We just reset the stack to its "init" state. */
If so we reset the state to ASM_INIT. */
static void
pop_asm_state (top_ok_p)
int top_ok_p;
{
if (cur_state_index == 0)
if (cur_state_level == 0)
{
if (top_ok_p)
asm_state_stack[cur_state_index] = ASM_INIT;
else
if (! top_ok_p)
as_fatal ("internal error: unexpected state pop");
CUR_ASM_STATE = ASM_INIT;
}
else
--cur_state_index;
--cur_state_level;
}
/* Set the top level assembler state. */
static void
set_asm_state (state)
set_asm_state (state, insn_name)
asm_state state;
const char *insn_name;
{
if (insn_name)
{
if (CUR_ASM_STATE != ASM_INIT)
as_bad ("illegal place for `%s' instruction", insn_name);
}
cur_state_level = 0;
CUR_ASM_STATE = state;
}
@ -1481,6 +1479,7 @@ md_operand (expressionP)
/* Advance over the '*'. */
++input_line_pointer;
return;
}
}
@ -1917,6 +1916,13 @@ md_apply_fix3 (fixP, valueP, seg)
}
}
/* ??? It might be cleaner to not do this at all here (when ! fx_done)
and leave it to bfd_install_relocation. */
if ((operand->flags & DVP_OPERAND_RELOC_U15_S3) != 0)
value >>= 3;
else if ((operand->flags & DVP_OPERAND_RELOC_11_S4) != 0)
value >>= 4;
/* Fetch the instruction, insert the fully resolved operand
value, and stuff the instruction back again. The fixup is recorded
at the appropriate word so pass DVP_MOD_THIS_WORD so any offset
@ -1978,6 +1984,26 @@ md_apply_fix3 (fixP, valueP, seg)
&& operand->shift == 4);
fixP->fx_r_type = BFD_RELOC_MIPS_DVP_27_S4;
}
else if ((operand->flags & DVP_OPERAND_RELOC_11_S4) != 0)
{
assert (operand->bits == 11
&& operand->shift == 0);
fixP->fx_r_type = BFD_RELOC_MIPS_DVP_11_S4;
/* ??? bfd_install_relocation will duplicate what we've done to
install the addend, so tell it not to. This is an instance
where setting partial_inplace to true has some use. */
value = 0;
}
else if ((operand->flags & DVP_OPERAND_RELOC_U15_S3) != 0)
{
assert (operand->bits == 15
&& operand->shift == 0);
fixP->fx_r_type = BFD_RELOC_MIPS_DVP_U15_S3;
/* ??? bfd_install_relocation will duplicate what we've done to
install the addend, so tell it not to. This is an instance
where setting partial_inplace to true has some use. */
value = 0;
}
else
{
as_bad_where (fixP->fx_file, fixP->fx_line,
@ -2142,12 +2168,20 @@ parse_float (pstr, errmsg)
char **pstr;
const char **errmsg;
{
LITTLENUM_TYPE words[MAX_LITTLENUMS];
char *p;
p = atof_ieee (*pstr, 'f', words);
*pstr = p;
return (words[0] << 16) | words[1];
if ((*pstr)[0] == '0'
&& ((*pstr)[1] == 'x' || (*pstr)[1] == 'X'))
{
long value;
(*pstr) += 2;
value = strtol (*pstr, pstr, 16);
return value;
}
else
{
LITTLENUM_TYPE words[MAX_LITTLENUMS];
*pstr = atof_ieee (*pstr, 'f', words);
return (words[0] << 16) | words[1];
}
}
/* Scan a symbol and return a pointer to one past the end. */
@ -3006,7 +3040,7 @@ s_enddirect (internal_p)
vif_data_end->sy_frag = frag_now;
S_SET_VALUE (vif_data_end, (valueT) frag_now_fix ());
set_asm_state (ASM_INIT);
pop_asm_state (1);
/* Needn't be reset, but to catch bugs it is. */
vif_data_end = NULL;
@ -3044,7 +3078,7 @@ s_endmpg (caller)
double words in this chunk. */
mpgloc_sym = compute_mpgloc (mpgloc_sym, vif_data_start, vif_data_end);
set_asm_state (ASM_INIT);
pop_asm_state (1);
/* Needn't be reset, but to catch bugs it is. */
vif_data_end = NULL;
@ -3081,7 +3115,7 @@ s_endunpack (internal_p)
/* Round up to next word boundary. */
frag_align (2, 0, 0);
set_asm_state (ASM_INIT);
pop_asm_state (1);
/* Needn't be reset, but to catch bugs it is. */
vif_data_end = NULL;
@ -3108,7 +3142,7 @@ s_endgif (ignore)
as_bad (".endgif doesn't follow a gif tag");
return;
}
pop_asm_state (0);
pop_asm_state (1);
/* Fill out to proper boundary.
??? This may cause eval_expr to always queue a fixup. So be it. */
@ -3189,33 +3223,29 @@ s_endgif (ignore)
}
static void
s_state (state)
int state;
s_vu (ignore)
int ignore;
{
/* If in MPG state and the user requests to change to VU state,
leave the state as MPG. This happens when we see an mpg followed
by a .include that has .vu. Note that no attempt is made to support
an include depth > 1 for this case. */
if (CUR_ASM_STATE == ASM_MPG && state == ASM_VU)
if (CUR_ASM_STATE == ASM_MPG)
return;
/* If changing to the VU state, we need to set up things for $.mpgloc
calculations. */
if (state == ASM_VU)
{
/* FIXME: May need to check that we're not clobbering currently
in use versions of these. Also need to worry about which section
the .vu is issued in. On the other hand, ".vu" isn't intended
to be supported everywhere. */
vif_data_start = expr_build_dot ();
mpgloc_sym = expr_build_uconstant (0);
/* We need to set up things for $.mpgloc calculations. */
/* FIXME: May need to check that we're not clobbering currently
in use versions of these. Also need to worry about which section
the .vu is issued in. On the other hand, ".vu" isn't intended
to be supported everywhere. */
vif_data_start = expr_build_dot ();
mpgloc_sym = expr_build_uconstant (0);
#if 0 /* ??? wip */
create_vuoverlay_section (vuoverlay_section_name (NULL), mpgloc_sym,
NULL, NULL);
create_vuoverlay_section (vuoverlay_section_name (NULL), mpgloc_sym,
NULL, NULL);
#endif
}
set_asm_state (state);
set_asm_state (ASM_VU, ".vu");
demand_empty_rest_of_line ();
}