aboutsummaryrefslogtreecommitdiff
path: root/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'cpu')
-rw-r--r--cpu/ChangeLog14
-rw-r--r--cpu/frv.cpu59
-rw-r--r--cpu/frv.opc667
3 files changed, 560 insertions, 180 deletions
diff --git a/cpu/ChangeLog b/cpu/ChangeLog
index ddbce32..859aa2a 100644
--- a/cpu/ChangeLog
+++ b/cpu/ChangeLog
@@ -1,3 +1,17 @@
+2005-01-25 Alexandre Oliva <aoliva@redhat.com>
+
+ 2004-11-10 Alexandre Oliva <aoliva@redhat.com>
+ * frv.cpu: Add support for TLS annotations in loads and calll.
+ * frv.opc (parse_symbolic_address): New.
+ (parse_ldd_annotation): New.
+ (parse_call_annotation): New.
+ (parse_ld_annotation): New.
+ (parse_ulo16, parse_uslo16): Use parse_symbolic_address.
+ Introduce TLS relocations.
+ (parse_d12, parse_s12, parse_u12): Likewise.
+ (parse_uhi16): Likewise. Fix constant checking on 64-bit host.
+ (parse_call_label, print_at): New.
+
2004-12-21 Mikael Starvik <starvik@axis.com>
* cris.cpu (cris-set-mem): Correct integral write semantics.
diff --git a/cpu/frv.cpu b/cpu/frv.cpu
index 720322d..8f00c00 100644
--- a/cpu/frv.cpu
+++ b/cpu/frv.cpu
@@ -2081,6 +2081,22 @@
(dnf f-LI-off "null field" (RESERVED) 25 1)
(dnf f-LI-on "null field" (RESERVED) 25 1)
+
+; Relocation annotations.
+(dsh h-reloc-ann "relocation annotation" () (register BI))
+(dnf f-reloc-ann "relocation annotation" () 0 0)
+
+(define-pmacro (dann xname xcomment xmode xparse xprint)
+ (define-operand
+ (name xname)
+ (comment xcomment)
+ (type h-reloc-ann)
+ (index f-reloc-ann)
+ (mode xmode)
+ (handlers (parse xparse) (print xprint))
+ )
+ )
+
; Enums.
@@ -3156,7 +3172,6 @@
(dnop ae "all entries indicator" (HASH-PREFIX) h-uint f-ae)
(dnop label16 "18 bit pc relative address" () h-iaddr f-label16)
-(dnop label24 "26 bit pc relative address" () h-iaddr f-label24)
(dnop LRAE "Load Real Address E flag" () h-uint f-LRAE)
(dnop LRAD "Load Real Address D flag" () h-uint f-LRAD)
@@ -3278,6 +3293,16 @@
(handlers (parse "uhi16") (print "hi"))
)
+(define-operand
+ (name label24)
+ (comment "26 bit pc relative address")
+ (attrs)
+ (type h-iaddr)
+ (index f-label24)
+ (mode SI)
+ (handlers (parse "call_label"))
+)
+
; operands representing hardware
;
(dnop psr_esr "PSR.ESR bit" (SEM-ONLY) h-psr_esr f-nil)
@@ -4295,12 +4320,12 @@
(fr500 (unit u-integer)) (fr550 (unit u-integer)))
)
-(define-pmacro (load-gr-r name mode op ope comment)
+(define-pmacro (load-gr-r name mode op ope comment ann)
(dni name
(comment)
((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2)
(FR400-MAJOR I-2) (FR450-MAJOR I-2))
- (.str name "$pack @($GRi,$GRj),$GRk")
+ (.str name "$pack " ann "($GRi,$GRj),$GRk")
(+ pack GRk op GRi ope GRj)
(set GRk (c-call mode (.str "@cpu@_read_mem_" mode) pc (add GRi GRj)))
((fr400 (unit u-gr-load)) (fr450 (unit u-gr-load))
@@ -4308,11 +4333,13 @@
)
)
-(load-gr-r ldsb QI OP_02 OPE1_00 "Load signed byte")
-(load-gr-r ldub UQI OP_02 OPE1_01 "Load unsigned byte")
-(load-gr-r ldsh HI OP_02 OPE1_02 "Load signed half")
-(load-gr-r lduh UHI OP_02 OPE1_03 "Load unsigned half")
-(load-gr-r ld SI OP_02 OPE1_04 "Load word")
+(dann ldann "ld annotation" SI "ld_annotation" "at")
+
+(load-gr-r ldsb QI OP_02 OPE1_00 "Load signed byte" "@")
+(load-gr-r ldub UQI OP_02 OPE1_01 "Load unsigned byte" "@")
+(load-gr-r ldsh HI OP_02 OPE1_02 "Load signed half" "@")
+(load-gr-r lduh UHI OP_02 OPE1_03 "Load unsigned half" "@")
+(load-gr-r ld SI OP_02 OPE1_04 "Load word" "$ldann")
(define-pmacro (load-fr-r name mode op ope comment)
(dni name
@@ -4414,12 +4441,12 @@
)
(define-pmacro (load-double-r-r
- name not_gr mode op ope regtype attr profile comment)
+ name not_gr mode op ope regtype attr profile comment ann)
(dni name
(comment)
((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2)
(FR400-MAJOR I-2) (FR450-MAJOR I-2) attr)
- (.str name "$pack @($GRi,$GRj),$" regtype "doublek")
+ (.str name "$pack " ann "($GRi,$GRj),$" regtype "doublek")
(+ pack (.sym regtype doublek) op GRi ope GRj)
(sequence ((WI address))
(load-double-semantics not_gr mode regtype address GRj))
@@ -4427,16 +4454,18 @@
)
)
+(dann lddann "ldd annotation" SI "ldd_annotation" "at")
+
(load-double-r-r ldd 0 DI OP_02 OPE1_05 GR NA
((fr400 (unit u-gr-load)) (fr450 (unit u-gr-load))
(fr500 (unit u-gr-load)) (fr550 (unit u-gr-load)))
- "Load double word")
+ "Load double word" "$lddann")
(load-double-r-r lddf 1 DF OP_02 OPE1_0B FR FR-ACCESS
((fr400 (unit u-fr-load)) (fr450 (unit u-fr-load))
(fr500 (unit u-fr-load)) (fr550 (unit u-fr-load)))
- "Load double float")
+ "Load double float" "@")
(load-double-r-r lddc 1 DI OP_02 OPE1_0E CPR (MACH frv) ()
- "Load coprocessor double")
+ "Load coprocessor double" "@")
(define-pmacro (ne-load-double-r-r
name not_gr mode op ope regtype size is_float attr profile
@@ -6128,11 +6157,13 @@
(fr500 (unit u-branch)) (fr550 (unit u-branch)))
)
+(dann callann "call annotation" SI "call_annotation" "at")
+
(dni calll
"call and link"
((UNIT I0) (FR500-MAJOR I-5) (FR550-MAJOR I-6)
(FR400-MAJOR I-5) (FR450-MAJOR I-5))
- "calll$pack @($GRi,$GRj)"
+ "calll$pack $callann($GRi,$GRj)"
(+ pack (misc-null-1) (LI-on) OP_0C GRi (misc-null-2) GRj)
(jump-and-link-semantics GRi GRj LI)
((fr400 (unit u-branch)) (fr450 (unit u-branch))
diff --git a/cpu/frv.opc b/cpu/frv.opc
index 46985b6..298252a 100644
--- a/cpu/frv.opc
+++ b/cpu/frv.opc
@@ -970,6 +970,146 @@ static const char * parse_A1
static const char * parse_A
PARAMS ((CGEN_CPU_DESC, const char **, int, long *, long));
+inline static const char *
+parse_symbolic_address (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ int opinfo,
+ enum cgen_parse_operand_result *resultp,
+ bfd_vma *valuep)
+{
+ enum cgen_parse_operand_result result_type;
+ const char *errmsg = (* cd->parse_operand_fn)
+ (cd, CGEN_PARSE_OPERAND_SYMBOLIC, strp, opindex, opinfo,
+ &result_type, valuep);
+
+ if (errmsg == NULL
+ && result_type != CGEN_PARSE_OPERAND_RESULT_QUEUED)
+ return "symbolic expression required";
+
+ if (resultp)
+ *resultp = result_type;
+
+ return errmsg;
+}
+
+static const char *
+parse_ldd_annotation (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ long *valuep)
+{
+ const char *errmsg;
+ enum cgen_parse_operand_result result_type;
+ bfd_vma value;
+
+ if (**strp == '#' || **strp == '%')
+ {
+ if (strncasecmp (*strp + 1, "tlsdesc(", 8) == 0)
+ {
+ *strp += 9;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_TLSDESC_RELAX,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing ')'";
+ if (valuep)
+ *valuep = value;
+ ++*strp;
+ if (errmsg)
+ return errmsg;
+ }
+ }
+
+ while (**strp == ' ' || **strp == '\t')
+ ++*strp;
+
+ if (**strp != '@')
+ return "missing `@'";
+
+ ++*strp;
+
+ return NULL;
+}
+
+static const char *
+parse_call_annotation (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ long *valuep)
+{
+ const char *errmsg;
+ enum cgen_parse_operand_result result_type;
+ bfd_vma value;
+
+ if (**strp == '#' || **strp == '%')
+ {
+ if (strncasecmp (*strp + 1, "gettlsoff(", 10) == 0)
+ {
+ *strp += 11;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GETTLSOFF_RELAX,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing ')'";
+ if (valuep)
+ *valuep = value;
+ ++*strp;
+ if (errmsg)
+ return errmsg;
+ }
+ }
+
+ while (**strp == ' ' || **strp == '\t')
+ ++*strp;
+
+ if (**strp != '@')
+ return "missing `@'";
+
+ ++*strp;
+
+ return NULL;
+}
+
+static const char *
+parse_ld_annotation (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ long *valuep)
+{
+ const char *errmsg;
+ enum cgen_parse_operand_result result_type;
+ bfd_vma value;
+
+ if (**strp == '#' || **strp == '%')
+ {
+ if (strncasecmp (*strp + 1, "tlsoff(", 7) == 0)
+ {
+ *strp += 8;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_TLSOFF_RELAX,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing ')'";
+ if (valuep)
+ *valuep = value;
+ ++*strp;
+ if (errmsg)
+ return errmsg;
+ }
+ }
+
+ while (**strp == ' ' || **strp == '\t')
+ ++*strp;
+
+ if (**strp != '@')
+ return "missing `@'";
+
+ ++*strp;
+
+ return NULL;
+}
+
static const char *
parse_ulo16 (cd, strp, opindex, valuep)
CGEN_CPU_DESC cd;
@@ -1000,73 +1140,96 @@ parse_ulo16 (cd, strp, opindex, valuep)
if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
{
*strp += 9;
- errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELLO,
- &result_type, &value);
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GPRELLO,
+ &result_type, &value);
if (**strp != ')')
return "missing ')'";
++*strp;
- if (errmsg == NULL
- && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
- value &= 0xffff;
*valuep = value;
return errmsg;
}
else if (strncasecmp (*strp + 1, "gotlo(", 6) == 0)
{
*strp += 7;
- errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GOTLO,
- &result_type, &value);
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GOTLO,
+ &result_type, &value);
if (**strp != ')')
return "missing ')'";
++*strp;
- if (errmsg == NULL
- && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
- value &= 0xffff;
*valuep = value;
return errmsg;
}
else if (strncasecmp (*strp + 1, "gotfuncdesclo(", 14) == 0)
{
*strp += 15;
- errmsg = cgen_parse_address (cd, strp, opindex,
- BFD_RELOC_FRV_FUNCDESC_GOTLO,
- &result_type, &value);
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_FUNCDESC_GOTLO,
+ &result_type, &value);
if (**strp != ')')
return "missing ')'";
++*strp;
- if (errmsg == NULL
- && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
- value &= 0xffff;
*valuep = value;
return errmsg;
}
else if (strncasecmp (*strp + 1, "gotofflo(", 9) == 0)
{
*strp += 10;
- errmsg = cgen_parse_address (cd, strp, opindex,
- BFD_RELOC_FRV_GOTOFFLO,
- &result_type, &value);
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GOTOFFLO,
+ &result_type, &value);
if (**strp != ')')
return "missing ')'";
++*strp;
- if (errmsg == NULL
- && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
- value &= 0xffff;
*valuep = value;
return errmsg;
}
else if (strncasecmp (*strp + 1, "gotofffuncdesclo(", 17) == 0)
{
*strp += 18;
- errmsg = cgen_parse_address (cd, strp, opindex,
- BFD_RELOC_FRV_FUNCDESC_GOTOFFLO,
- &result_type, &value);
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_FUNCDESC_GOTOFFLO,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing ')'";
+ ++*strp;
+ *valuep = value;
+ return errmsg;
+ }
+ else if (strncasecmp (*strp + 1, "gottlsdesclo(", 13) == 0)
+ {
+ *strp += 14;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GOTTLSDESCLO,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing ')'";
+ ++*strp;
+ *valuep = value;
+ return errmsg;
+ }
+ else if (strncasecmp (*strp + 1, "tlsmofflo(", 10) == 0)
+ {
+ *strp += 11;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_TLSMOFFLO,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing ')'";
+ ++*strp;
+ *valuep = value;
+ return errmsg;
+ }
+ else if (strncasecmp (*strp + 1, "gottlsofflo(", 12) == 0)
+ {
+ *strp += 13;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GOTTLSOFFLO,
+ &result_type, &value);
if (**strp != ')')
return "missing ')'";
++*strp;
- if (errmsg == NULL
- && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
- value &= 0xffff;
*valuep = value;
return errmsg;
}
@@ -1104,73 +1267,96 @@ parse_uslo16 (cd, strp, opindex, valuep)
else if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
{
*strp += 9;
- errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELLO,
- &result_type, &value);
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GPRELLO,
+ &result_type, &value);
if (**strp != ')')
return "missing ')'";
++*strp;
- if (errmsg == NULL
- && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
- value &= 0xffff;
*valuep = value;
return errmsg;
}
else if (strncasecmp (*strp + 1, "gotlo(", 6) == 0)
{
*strp += 7;
- errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GOTLO,
- &result_type, &value);
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GOTLO,
+ &result_type, &value);
if (**strp != ')')
return "missing ')'";
++*strp;
- if (errmsg == NULL
- && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
- value &= 0xffff;
*valuep = value;
return errmsg;
}
else if (strncasecmp (*strp + 1, "gotfuncdesclo(", 14) == 0)
{
*strp += 15;
- errmsg = cgen_parse_address (cd, strp, opindex,
- BFD_RELOC_FRV_FUNCDESC_GOTLO,
- &result_type, &value);
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_FUNCDESC_GOTLO,
+ &result_type, &value);
if (**strp != ')')
return "missing ')'";
++*strp;
- if (errmsg == NULL
- && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
- value &= 0xffff;
*valuep = value;
return errmsg;
}
else if (strncasecmp (*strp + 1, "gotofflo(", 9) == 0)
{
*strp += 10;
- errmsg = cgen_parse_address (cd, strp, opindex,
- BFD_RELOC_FRV_GOTOFFLO,
- &result_type, &value);
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GOTOFFLO,
+ &result_type, &value);
if (**strp != ')')
return "missing ')'";
++*strp;
- if (errmsg == NULL
- && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
- value &= 0xffff;
*valuep = value;
return errmsg;
}
else if (strncasecmp (*strp + 1, "gotofffuncdesclo(", 17) == 0)
{
*strp += 18;
- errmsg = cgen_parse_address (cd, strp, opindex,
- BFD_RELOC_FRV_FUNCDESC_GOTOFFLO,
- &result_type, &value);
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_FUNCDESC_GOTOFFLO,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing ')'";
+ ++*strp;
+ *valuep = value;
+ return errmsg;
+ }
+ else if (strncasecmp (*strp + 1, "gottlsdesclo(", 13) == 0)
+ {
+ *strp += 14;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GOTTLSDESCLO,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing ')'";
+ ++*strp;
+ *valuep = value;
+ return errmsg;
+ }
+ else if (strncasecmp (*strp + 1, "tlsmofflo(", 10) == 0)
+ {
+ *strp += 11;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_TLSMOFFLO,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing ')'";
+ ++*strp;
+ *valuep = value;
+ return errmsg;
+ }
+ else if (strncasecmp (*strp + 1, "gottlsofflo(", 12) == 0)
+ {
+ *strp += 13;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GOTTLSOFFLO,
+ &result_type, &value);
if (**strp != ')')
return "missing ')'";
++*strp;
- if (errmsg == NULL
- && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
- value &= 0xffff;
*valuep = value;
return errmsg;
}
@@ -1201,80 +1387,110 @@ parse_uhi16 (cd, strp, opindex, valuep)
++*strp;
if (errmsg == NULL
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
- value >>= 16;
+ {
+ /* If bfd_vma is wider than 32 bits, but we have a sign-
+ or zero-extension, truncate it. */
+ if (value >= - ((bfd_vma)1 << 31)
+ || value <= ((bfd_vma)1 << 31) - (bfd_vma)1)
+ value &= (((bfd_vma)1 << 16) << 16) - 1;
+ value >>= 16;
+ }
*valuep = value;
return errmsg;
}
else if (strncasecmp (*strp + 1, "gprelhi(", 8) == 0)
{
*strp += 9;
- errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELHI,
- &result_type, &value);
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GPRELHI,
+ &result_type, &value);
if (**strp != ')')
return "missing ')'";
++*strp;
- if (errmsg == NULL
- && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
- value >>= 16;
*valuep = value;
return errmsg;
}
else if (strncasecmp (*strp + 1, "gothi(", 6) == 0)
{
*strp += 7;
- errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GOTHI,
- &result_type, &value);
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GOTHI,
+ &result_type, &value);
if (**strp != ')')
return "missing ')'";
++*strp;
- if (errmsg == NULL
- && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
- value >>= 16;
*valuep = value;
return errmsg;
}
else if (strncasecmp (*strp + 1, "gotfuncdeschi(", 14) == 0)
{
*strp += 15;
- errmsg = cgen_parse_address (cd, strp, opindex,
- BFD_RELOC_FRV_FUNCDESC_GOTHI,
- &result_type, &value);
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_FUNCDESC_GOTHI,
+ &result_type, &value);
if (**strp != ')')
return "missing ')'";
++*strp;
- if (errmsg == NULL
- && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
- value >>= 16;
*valuep = value;
return errmsg;
}
else if (strncasecmp (*strp + 1, "gotoffhi(", 9) == 0)
{
*strp += 10;
- errmsg = cgen_parse_address (cd, strp, opindex,
- BFD_RELOC_FRV_GOTOFFHI,
- &result_type, &value);
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GOTOFFHI,
+ &result_type, &value);
if (**strp != ')')
return "missing ')'";
++*strp;
- if (errmsg == NULL
- && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
- value >>= 16;
*valuep = value;
return errmsg;
}
else if (strncasecmp (*strp + 1, "gotofffuncdeschi(", 17) == 0)
{
*strp += 18;
- errmsg = cgen_parse_address (cd, strp, opindex,
- BFD_RELOC_FRV_FUNCDESC_GOTOFFHI,
- &result_type, &value);
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_FUNCDESC_GOTOFFHI,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing ')'";
+ ++*strp;
+ *valuep = value;
+ return errmsg;
+ }
+ else if (strncasecmp (*strp + 1, "gottlsdeschi(", 13) == 0)
+ {
+ *strp += 14;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GOTTLSDESCHI,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing ')'";
+ ++*strp;
+ *valuep = value;
+ return errmsg;
+ }
+ else if (strncasecmp (*strp + 1, "tlsmoffhi(", 10) == 0)
+ {
+ *strp += 11;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_TLSMOFFHI,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing ')'";
+ ++*strp;
+ *valuep = value;
+ return errmsg;
+ }
+ else if (strncasecmp (*strp + 1, "gottlsoffhi(", 12) == 0)
+ {
+ *strp += 13;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GOTTLSOFFHI,
+ &result_type, &value);
if (**strp != ')')
return "missing ')'";
++*strp;
- if (errmsg == NULL
- && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
- value >>= 16;
*valuep = value;
return errmsg;
}
@@ -1352,8 +1568,9 @@ parse_d12 (cd, strp, opindex, valuep)
if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
{
*strp += 9;
- errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPREL12,
- &result_type, &value);
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GPREL12,
+ &result_type, &value);
if (**strp != ')')
return "missing `)'";
++*strp;
@@ -1363,8 +1580,9 @@ parse_d12 (cd, strp, opindex, valuep)
else if (strncasecmp (*strp + 1, "got12(", 6) == 0)
{
*strp += 7;
- errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GOT12,
- &result_type, &value);
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GOT12,
+ &result_type, &value);
if (**strp != ')')
return "missing ')'";
++*strp;
@@ -1374,9 +1592,9 @@ parse_d12 (cd, strp, opindex, valuep)
else if (strncasecmp (*strp + 1, "gotfuncdesc12(", 14) == 0)
{
*strp += 15;
- errmsg = cgen_parse_address (cd, strp, opindex,
- BFD_RELOC_FRV_FUNCDESC_GOT12,
- &result_type, &value);
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_FUNCDESC_GOT12,
+ &result_type, &value);
if (**strp != ')')
return "missing ')'";
++*strp;
@@ -1386,9 +1604,9 @@ parse_d12 (cd, strp, opindex, valuep)
else if (strncasecmp (*strp + 1, "gotoff12(", 9) == 0)
{
*strp += 10;
- errmsg = cgen_parse_address (cd, strp, opindex,
- BFD_RELOC_FRV_GOTOFF12,
- &result_type, &value);
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GOTOFF12,
+ &result_type, &value);
if (**strp != ')')
return "missing ')'";
++*strp;
@@ -1398,9 +1616,45 @@ parse_d12 (cd, strp, opindex, valuep)
else if (strncasecmp (*strp + 1, "gotofffuncdesc12(", 17) == 0)
{
*strp += 18;
- errmsg = cgen_parse_address (cd, strp, opindex,
- BFD_RELOC_FRV_FUNCDESC_GOTOFF12,
- &result_type, &value);
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_FUNCDESC_GOTOFF12,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing ')'";
+ ++*strp;
+ *valuep = value;
+ return errmsg;
+ }
+ else if (strncasecmp (*strp + 1, "gottlsdesc12(", 13) == 0)
+ {
+ *strp += 14;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GOTTLSDESC12,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing ')'";
+ ++*strp;
+ *valuep = value;
+ return errmsg;
+ }
+ else if (strncasecmp (*strp + 1, "tlsmoff12(", 10) == 0)
+ {
+ *strp += 11;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_TLSMOFF12,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing ')'";
+ ++*strp;
+ *valuep = value;
+ return errmsg;
+ }
+ else if (strncasecmp (*strp + 1, "gottlsoff12(", 12) == 0)
+ {
+ *strp += 13;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GOTTLSOFF12,
+ &result_type, &value);
if (**strp != ')')
return "missing ')'";
++*strp;
@@ -1423,74 +1677,109 @@ parse_s12 (cd, strp, opindex, valuep)
bfd_vma value;
/* Check for small data reference. */
- if ((**strp == '#' || **strp == '%')
- && strncasecmp (*strp + 1, "gprel12(", 8) == 0)
- {
- *strp += 9;
- errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPREL12,
- &result_type, &value);
- if (**strp != ')')
- return "missing `)'";
- ++*strp;
- *valuep = value;
- return errmsg;
- }
- else if ((**strp == '#' || **strp == '%')
- && strncasecmp (*strp + 1, "got12(", 6) == 0)
- {
- *strp += 7;
- errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GOT12,
- &result_type, &value);
- if (**strp != ')')
- return "missing ')'";
- ++*strp;
- *valuep = value;
- return errmsg;
- }
- else if ((**strp == '#' || **strp == '%')
- && strncasecmp (*strp + 1, "gotfuncdesc12(", 14) == 0)
- {
- *strp += 15;
- errmsg = cgen_parse_address (cd, strp, opindex,
- BFD_RELOC_FRV_FUNCDESC_GOT12,
- &result_type, &value);
- if (**strp != ')')
- return "missing ')'";
- ++*strp;
- *valuep = value;
- return errmsg;
- }
- else if ((**strp == '#' || **strp == '%')
- && strncasecmp (*strp + 1, "gotoff12(", 9) == 0)
- {
- *strp += 10;
- errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GOTOFF12,
- &result_type, &value);
- if (**strp != ')')
- return "missing ')'";
- ++*strp;
- *valuep = value;
- return errmsg;
- }
- else if ((**strp == '#' || **strp == '%')
- && strncasecmp (*strp + 1, "gotofffuncdesc12(", 17) == 0)
- {
- *strp += 18;
- errmsg = cgen_parse_address (cd, strp, opindex,
- BFD_RELOC_FRV_FUNCDESC_GOTOFF12,
- &result_type, &value);
- if (**strp != ')')
- return "missing ')'";
- ++*strp;
- *valuep = value;
- return errmsg;
- }
- else
+ if (**strp == '#' || **strp == '%')
{
- if (**strp == '#')
- ++*strp;
- return cgen_parse_signed_integer (cd, strp, opindex, valuep);
+ if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
+ {
+ *strp += 9;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GPREL12,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing `)'";
+ ++*strp;
+ *valuep = value;
+ return errmsg;
+ }
+ else if (strncasecmp (*strp + 1, "got12(", 6) == 0)
+ {
+ *strp += 7;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GOT12,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing ')'";
+ ++*strp;
+ *valuep = value;
+ return errmsg;
+ }
+ else if (strncasecmp (*strp + 1, "gotfuncdesc12(", 14) == 0)
+ {
+ *strp += 15;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_FUNCDESC_GOT12,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing ')'";
+ ++*strp;
+ *valuep = value;
+ return errmsg;
+ }
+ else if (strncasecmp (*strp + 1, "gotoff12(", 9) == 0)
+ {
+ *strp += 10;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GOTOFF12,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing ')'";
+ ++*strp;
+ *valuep = value;
+ return errmsg;
+ }
+ else if (strncasecmp (*strp + 1, "gotofffuncdesc12(", 17) == 0)
+ {
+ *strp += 18;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_FUNCDESC_GOTOFF12,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing ')'";
+ ++*strp;
+ *valuep = value;
+ return errmsg;
+ }
+ else if (strncasecmp (*strp + 1, "gottlsdesc12(", 13) == 0)
+ {
+ *strp += 14;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GOTTLSDESC12,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing ')'";
+ ++*strp;
+ *valuep = value;
+ return errmsg;
+ }
+ else if (strncasecmp (*strp + 1, "tlsmoff12(", 10) == 0)
+ {
+ *strp += 11;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_TLSMOFF12,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing ')'";
+ ++*strp;
+ *valuep = value;
+ return errmsg;
+ }
+ else if (strncasecmp (*strp + 1, "gottlsoff12(", 12) == 0)
+ {
+ *strp += 13;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GOTTLSOFF12,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing ')'";
+ ++*strp;
+ *valuep = value;
+ return errmsg;
+ }
}
+
+ if (**strp == '#')
+ ++*strp;
+ return cgen_parse_signed_integer (cd, strp, opindex, valuep);
}
static const char *
@@ -1509,8 +1798,9 @@ parse_u12 (cd, strp, opindex, valuep)
&& strncasecmp (*strp + 1, "gprel12(", 8) == 0)
{
*strp += 9;
- errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELU12,
- &result_type, &value);
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GPRELU12,
+ &result_type, &value);
if (**strp != ')')
return "missing `)'";
++*strp;
@@ -1588,6 +1878,38 @@ parse_even_register (cd, strP, tableP, valueP)
return errmsg;
}
+
+static const char *
+parse_call_label (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ int opinfo,
+ enum cgen_parse_operand_result *resultp,
+ bfd_vma *valuep)
+{
+ const char *errmsg;
+ bfd_vma value;
+
+ /* Check for small data reference. */
+ if (opinfo == 0 && (**strp == '#' || **strp == '%'))
+ {
+ if (strncasecmp (*strp + 1, "gettlsoff(", 10) == 0)
+ {
+ *strp += 11;
+ errmsg = parse_symbolic_address (cd, strp, opindex,
+ BFD_RELOC_FRV_GETTLSOFF,
+ resultp, &value);
+ if (**strp != ')')
+ return "missing `)'";
+ ++*strp;
+ *valuep = value;
+ return errmsg;
+ }
+ }
+
+ return cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep);
+}
+
/* -- */
/* -- dis.c */
@@ -1599,6 +1921,19 @@ static void print_lo
PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int));
static void
+print_at (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
+ PTR dis_info,
+ long reloc_ann ATTRIBUTE_UNUSED,
+ long value ATTRIBUTE_UNUSED,
+ bfd_vma pc ATTRIBUTE_UNUSED,
+ int length ATTRIBUTE_UNUSED
+ )
+{
+ disassemble_info *info = (disassemble_info *) dis_info;
+ (*info->fprintf_func) (info->stream, "@");
+}
+
+static void
print_spr (cd, dis_info, names, regno, attrs)
CGEN_CPU_DESC cd;
PTR dis_info;