diff options
-rw-r--r-- | gas/ChangeLog | 14 | ||||
-rw-r--r-- | gas/config/tc-v850.c | 191 | ||||
-rw-r--r-- | gas/doc/c-v850.texi | 17 |
3 files changed, 145 insertions, 77 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index ee2372b..852303a 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,17 @@ +Wed Sep 17 16:54:20 1997 Nick Clifton <nickc@cygnus.com> + + * config/tc-v850.c (v850_reloc_prefix): Recoded to use CHECK_ () + macro. + (handle_tdaoff, handle_zdaoff, handle_sdaoff): New functions. +start-sanitize-v850e + * config/tc-v850.c Add new sections: call_table_data and + call_table_text. + (v850_reloc_prefix): Add support for ctoff() relocation prefix. + (handle_ctoff): New Function. + + * doc/c-v850.texi (V850 Opcodes): Document call table relocations. +end-sanitize-v850e + Tue Sep 16 14:18:22 1997 Nick Clifton <nickc@cygnus.com> * config/tc-v850.c (v850_reloc_prefix): Add support for a 16 bit diff --git a/gas/config/tc-v850.c b/gas/config/tc-v850.c index 333a809..bd80de7 100644 --- a/gas/config/tc-v850.c +++ b/gas/config/tc-v850.c @@ -83,6 +83,10 @@ static segT tbss_section = NULL; static segT zbss_section = NULL; static segT rosdata_section = NULL; static segT rozdata_section = NULL; +/* start-sanitize-v850e */ +static segT call_table_data_section = NULL; +static segT call_table_text_section = NULL; +/* end-sanitize-v850e */ /* local functions */ @@ -166,6 +170,24 @@ v850_rozdata (int ignore) demand_empty_rest_of_line (); } +/* start-sanitize-v850e */ +void +v850_call_table_data (int ignore) +{ + subseg_set (call_table_data_section, (subsegT) get_absolute_expression ()); + + demand_empty_rest_of_line (); +} + +void +v850_call_table_text (int ignore) +{ + subseg_set (call_table_text_section, (subsegT) get_absolute_expression ()); + + demand_empty_rest_of_line (); +} +/* end-sanitize-v850e */ + static void v850_section (int arg) { @@ -244,10 +266,12 @@ const pseudo_typeS md_pseudo_table[] = {"word", cons, 4}, {"v850", set_machine, 0}, /* start-sanitize-v850e */ - {"v850e", set_machine, bfd_mach_v850e}, + {"call_table_data", v850_call_table_data, 0}, + {"call_table_text", v850_call_table_text, 0}, + {"v850e", set_machine, bfd_mach_v850e}, /* end-sanitize-v850e */ /* start-sanitize-v850eq */ - {"v850eq", set_machine, bfd_mach_v850eq}, + {"v850eq", set_machine, bfd_mach_v850eq}, /* end-sanitize-v850eq */ { NULL, NULL, 0} }; @@ -509,7 +533,7 @@ system_register_name (expressionP, accept_numbers) */ static boolean cc_name (expressionP) - expressionS *expressionP; + expressionS * expressionP; { int reg_number; char * name; @@ -791,7 +815,7 @@ size_t md_longopts_size = sizeof md_longopts; void md_show_usage (stream) - FILE *stream; + FILE * stream; { fprintf (stream, "V850 options:\n"); fprintf (stream, "\t-wsigned_overflow Warn if signed immediate values overflow\n"); @@ -1003,8 +1027,78 @@ md_begin () rozdata_section = subseg_new (".rozdata", 0); bfd_set_section_flags (stdoutput, rozdata_section, applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY)); + +/* start-sanitize-v850e */ + call_table_data_section = subseg_new (".call_table_data", 0); + bfd_set_section_flags (stdoutput, call_table_data_section, applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS)); + + call_table_text_section = subseg_new (".call_table_text", 0); + bfd_set_section_flags (stdoutput, call_table_text_section, applicable & (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE)); +/* end-sanitize-v850e */ +} + + +/* start-sanitize-v850e */ +static bfd_reloc_code_real_type +handle_ctoff (const struct v850_operand * operand) +{ + if (operand == NULL) + return BFD_RELOC_V850_CALLT_16_16_OFFSET; + + assert (operand->bits == 6); + assert (operand->shift == 0); + + return BFD_RELOC_V850_CALLT_6_7_OFFSET; +} +/* end-sanitize-v850e */ + +static bfd_reloc_code_real_type +handle_sdaoff (const struct v850_operand * operand) +{ + if (operand == NULL) return BFD_RELOC_V850_SDA_16_16_OFFSET; + if (operand->bits == 15 && operand->shift == 17) return BFD_RELOC_V850_SDA_15_16_OFFSET; + /* start-sanitize-v850e */ + if (operand->bits == -1) return BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET; + /* end-sanitize-v850e */ + + assert (operand->bits == 16); + assert (operand->shift == 16); + + return BFD_RELOC_V850_SDA_16_16_OFFSET; +} + +static bfd_reloc_code_real_type +handle_zdaoff (const struct v850_operand * operand) +{ + if (operand == NULL) return BFD_RELOC_V850_ZDA_16_16_OFFSET; + if (operand->bits == 15 && operand->shift == 17) return BFD_RELOC_V850_ZDA_15_16_OFFSET; + /* start-sanitize-v850e */ + if (operand->bits == -1) return BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET; + /* end-sanitize-v850e */ + + assert (operand->bits == 16); + assert (operand->shift == 16); + + return BFD_RELOC_V850_ZDA_16_16_OFFSET; } +static bfd_reloc_code_real_type +handle_tdaoff (const struct v850_operand * operand) +{ + if (operand == NULL) return BFD_RELOC_V850_TDA_7_7_OFFSET; /* data item, not an instruction. */ + if (operand->bits == 6 && operand->shift == 1) return BFD_RELOC_V850_TDA_6_8_OFFSET; /* sld.w/sst.w, operand: D8_6 */ + /* start-sanitize-v850e */ + if (operand->bits == 4 && operand->insert != NULL) return BFD_RELOC_V850_TDA_4_5_OFFSET; /* sld.hu, operand: D5-4 */ + if (operand->bits == 4 && operand->insert == NULL) return BFD_RELOC_V850_TDA_4_4_OFFSET; /* sld.bu, operand: D4 */ + /* end-sanitize-v850e */ + if (operand->bits == 16 && operand->shift == 16) return BFD_RELOC_V850_TDA_16_16_OFFSET; /* set1 & chums, operands: D16 */ + + assert (operand->bits == 7); + + return operand->insert != NULL + ? BFD_RELOC_V850_TDA_7_8_OFFSET /* sld.h/sst.h, operand: D8_7 */ + : BFD_RELOC_V850_TDA_7_7_OFFSET; /* sld.b/sst.b, opreand: D7 */ +} /* Warning: The code in this function relies upon the definitions in the v850_operands[] array (defined in opcodes/v850-opc.c) @@ -1022,83 +1116,28 @@ v850_reloc_prefix (const struct v850_operand * operand) ++ input_line_pointer; paren_skipped = true; } - - if (strncmp (input_line_pointer, "hi0(", 4) == 0) - { - input_line_pointer += 3; - return BFD_RELOC_HI16; - } - if (strncmp (input_line_pointer, "hi(", 3) == 0) - { - input_line_pointer += 2; - return BFD_RELOC_HI16_S; - } - if (strncmp (input_line_pointer, "lo(", 3) == 0) - { - input_line_pointer += 2; - return BFD_RELOC_LO16; - } -/* start-sanitize-v850e */ - if (strncmp (input_line_pointer, "hilo(", 5) == 0) - { - input_line_pointer += 4; - return BFD_RELOC_32; - } -/* end-sanitize-v850e */ - if (strncmp (input_line_pointer, "sdaoff(", 7) == 0) - { - input_line_pointer += 6; - - if (operand == NULL) return BFD_RELOC_V850_SDA_16_16_OFFSET; - if (operand->bits == 15 && operand->shift == 17) return BFD_RELOC_V850_SDA_15_16_OFFSET; - /* start-sanitize-v850e */ - if (operand->bits == -1) return BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET; - /* end-sanitize-v850e */ - - assert (operand->bits == 16); - assert (operand->shift == 16); - - return BFD_RELOC_V850_SDA_16_16_OFFSET; - } - - if (strncmp (input_line_pointer, "zdaoff(", 7) == 0) - { - input_line_pointer += 6; - - if (operand == NULL) return BFD_RELOC_V850_ZDA_16_16_OFFSET; - if (operand->bits == 15 && operand->shift == 17) return BFD_RELOC_V850_ZDA_15_16_OFFSET; - /* start-sanitize-v850e */ - if (operand->bits == -1) return BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET; - /* end-sanitize-v850e */ - - assert (operand->bits == 16); - assert (operand->shift == 16); - - return BFD_RELOC_V850_ZDA_16_16_OFFSET; +#define CHECK_(name, reloc) \ + if (strncmp (input_line_pointer, name##"(", strlen (name) + 1) == 0) \ + { \ + input_line_pointer += strlen (name); \ + return reloc; \ } - if (strncmp (input_line_pointer, "tdaoff(", 7) == 0) - { - input_line_pointer += 6; - - if (operand == NULL) return BFD_RELOC_V850_TDA_7_7_OFFSET; - if (operand->bits == 6 && operand->shift == 1) return BFD_RELOC_V850_TDA_6_8_OFFSET; /* sld.w/sst.w, operand: D8_6 */ - /* start-sanitize-v850e */ - if (operand->bits == 4 && operand->insert != NULL) return BFD_RELOC_V850_TDA_4_5_OFFSET; /* sld.hu, operand: D5-4 */ - if (operand->bits == 4 && operand->insert == NULL) return BFD_RELOC_V850_TDA_4_4_OFFSET; /* sld.bu, operand: D4 */ - /* end-sanitize-v850e */ - if (operand->bits == 16 && operand->shift == 16) return BFD_RELOC_V850_TDA_16_16_OFFSET; /* set1 & chums, operands: D16 */ - - assert (operand->bits == 7); - - return operand->insert != NULL - ? BFD_RELOC_V850_TDA_7_8_OFFSET /* sld.h/sst.h, operand: D8_7 */ - : BFD_RELOC_V850_TDA_7_7_OFFSET; /* sld.b/sst.b, opreand: D7 */ - } + CHECK_ ("hi0", BFD_RELOC_HI16); + CHECK_ ("hi", BFD_RELOC_HI16_S); + CHECK_ ("lo", BFD_RELOC_LO16); + CHECK_ ("sdaoff", handle_sdaoff (operand)); + CHECK_ ("zdaoff", handle_zdaoff (operand)); + CHECK_ ("tdaoff", handle_tdaoff (operand)); +/* start-sanitize-v850e */ + CHECK_ ("hilo", BFD_RELOC_32); + CHECK_ ("ctoff", handle_ctoff (operand)); +/* end-sanitize-v850e */ + + /* Restore skipped parenthesis. */ if (paren_skipped) - /* Restore skipped character. */ -- input_line_pointer; return BFD_RELOC_UNUSED; diff --git a/gas/doc/c-v850.texi b/gas/doc/c-v850.texi index b17fc36..06919ff 100644 --- a/gas/doc/c-v850.texi +++ b/gas/doc/c-v850.texi @@ -358,10 +358,25 @@ that the label is somewhere within the first 32K of memory. (Strictly speaking it also possible to access the last 32K of memory as well, as the offsets are signed). +@c start-santize-v850e +@cindex @code{ctoff} pseudo-op, V850 +@item ctoff() +Computes the offset of the named variable from the start of the Call +Table Area (whoes address is helg in system register 20, the CTBP +register) and stores the result a 6 or 16 bit unsigned value in the +immediate field of then given instruction or piece of data. For +example: + + @samp{callt ctoff(table_func1)} + +will put the call the function whoes address is held in the call table +at the location labeled 'table_func1'. +@c end-santize-v850e + @end table -For information on the V850 or Thumb instruction sets, see @cite{V850 +For information on the V850 instruction set, see @cite{V850 Family 32-/16-Bit single-Chip Microcontroller Architecture Manual} from NEC. Ltd. |