diff options
author | Jakub Jelinek <jakub@redhat.com> | 2003-08-29 20:20:18 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2003-08-29 20:20:18 +0000 |
commit | 364b6d8b23fffbc773c2bda23348d73e8de86e84 (patch) | |
tree | ffe7b74218f18af4d967a05c8fb7bb373ca2161d /gas/config/tc-sparc.c | |
parent | e294916c5a6fd7e6f6a13261100cb1d3a2ee5a82 (diff) | |
download | gdb-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.c | 68 |
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; } |