aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-sparc.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2003-08-29 20:20:18 +0000
committerJakub Jelinek <jakub@redhat.com>2003-08-29 20:20:18 +0000
commit364b6d8b23fffbc773c2bda23348d73e8de86e84 (patch)
treeffe7b74218f18af4d967a05c8fb7bb373ca2161d /gas/config/tc-sparc.c
parente294916c5a6fd7e6f6a13261100cb1d3a2ee5a82 (diff)
downloadgdb-364b6d8b23fffbc773c2bda23348d73e8de86e84.zip
gdb-364b6d8b23fffbc773c2bda23348d73e8de86e84.tar.gz
gdb-364b6d8b23fffbc773c2bda23348d73e8de86e84.tar.bz2
* dw2gencfi.c (cfi_pseudo_table): Add cfi_gnu_window_save.
(dot_cfi, output_cfi_insn): Handle DW_CFA_GNU_window_save. (output_cie): Don't use DW_EH_PE_pcrel if neither DIFF_EXPR_OK nor tc_cfi_emit_pcrel_expr are defined. (output_fde): Use tc_cfi_emit_pcrel_expr if available and DIFF_EXPR_OK is not defined. * config/tc-sparc.h (TARGET_USE_CFIPOP): Define. (tc_cfi_frame_initial_instructions, tc_regname_to_dw2regnum, tc_cfi_emit_pcrel_expr): Define. (sparc_cfi_frame_initial_instructions, sparc_regname_to_dw2regnum, sparc_cfi_emit_pcrel_expr): New prototypes. (sparc_cie_data_alignment): New decl. (DWARF2_DEFAULT_RETURN_COLUMN, DWARF2_CIE_DATA_ALIGNMENT): Define. * config/tc-sparc.c: Include dw2gencfi.h. (sparc_cie_data_alignment): New variable. (md_begin): Initialize it. (sparc_cfi_frame_initial_instructions): New function. (sparc_regname_to_dw2regnum): Likewise. (sparc_cfi_emit_pcrel_expr): Likewise. * doc/as.texinfo: Document .cfi_gnu_window_save. * config/tc-sparc.c (s_common): Cast last argument to long and change format string to shut up warning. testsuite/ * gas/cfi/cfi-sparc-1.s: New test. * gas/cfi/cfi-sparc-1.d: New test. * gas/cfi/cfi-sparc64-1.s: New test. * gas/cfi/cfi-sparc64-1.d: New test. * gas/cfi/cfi.exp: Run them.
Diffstat (limited to 'gas/config/tc-sparc.c')
-rw-r--r--gas/config/tc-sparc.c68
1 files changed, 66 insertions, 2 deletions
diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c
index 2278411..f3ef720 100644
--- a/gas/config/tc-sparc.c
+++ b/gas/config/tc-sparc.c
@@ -26,6 +26,7 @@
#include "subsegs.h"
#include "opcode/sparc.h"
+#include "dw2gencfi.h"
#ifdef OBJ_ELF
#include "elf/sparc.h"
@@ -116,6 +117,9 @@ static int target_little_endian_data;
/* Symbols for global registers on v9. */
static symbolS *globals[8];
+/* The dwarf2 data alignment, adjusted for 32 or 64 bit. */
+int sparc_cie_data_alignment;
+
/* V9 and 86x have big and little endian data, but instructions are always big
endian. The sparclet has bi-endian support but both data and insns have
the same endianness. Global `target_big_endian' is used for data.
@@ -798,6 +802,7 @@ md_begin ()
if (! default_init_p)
init_default_arch ();
+ sparc_cie_data_alignment = sparc_arch_size == 64 ? -8 : -4;
op_hash = hash_new ();
while (i < (unsigned int) sparc_num_opcodes)
@@ -3804,8 +3809,8 @@ s_common (ignore)
{
if (S_GET_VALUE (symbolP) != (valueT) size)
{
- as_warn (_("Length of .comm \"%s\" is already %ld. Not changed to %d."),
- S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
+ as_warn (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
+ S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), (long) size);
}
}
else
@@ -4482,4 +4487,63 @@ cons_fix_new_sparc (frag, where, nbytes, exp)
}
fix_new_exp (frag, where, (int) nbytes, exp, 0, r);
+ sparc_cons_special_reloc = NULL;
+}
+
+void
+sparc_cfi_frame_initial_instructions ()
+{
+ cfi_add_CFA_def_cfa (14, sparc_arch_size == 64 ? 0x7ff : 0);
+}
+
+int
+sparc_regname_to_dw2regnum (const char *regname)
+{
+ char *p, *q;
+
+ if (!regname[0])
+ return -1;
+
+ q = "goli";
+ p = strchr (q, regname[0]);
+ if (p)
+ {
+ if (regname[1] < '0' || regname[1] > '8' || regname[2])
+ return -1;
+ return (p - q) * 8 + regname[1] - '0';
+ }
+ if (regname[0] == 's' && regname[1] == 'p' && !regname[2])
+ return 14;
+ if (regname[0] == 'f' && regname[1] == 'p' && !regname[2])
+ return 30;
+ if (regname[0] == 'f' || regname[0] == 'r')
+ {
+ unsigned int regnum;
+
+ regnum = strtoul (regname + 1, &q, 10);
+ if (p == q || *q)
+ return -1;
+ if (regnum >= ((regname[0] == 'f'
+ && SPARC_OPCODE_ARCH_V9_P (max_architecture))
+ ? 64 : 32))
+ return -1;
+ if (regname[0] == 'f')
+ {
+ regnum += 32;
+ if (regnum >= 64 && (regnum & 1))
+ return -1;
+ }
+ return regnum;
+ }
+ return -1;
+}
+
+void
+sparc_cfi_emit_pcrel_expr (expressionS *exp, unsigned int nbytes)
+{
+ sparc_cons_special_reloc = "disp";
+ sparc_no_align_cons = 1;
+ emit_expr (exp, nbytes);
+ sparc_no_align_cons = 0;
+ sparc_cons_special_reloc = NULL;
}