1*e4b17023SJohn Marino /* Dwarf2 assembler output helper routines. 2*e4b17023SJohn Marino Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011 3*e4b17023SJohn Marino Free Software Foundation, Inc. 4*e4b17023SJohn Marino 5*e4b17023SJohn Marino This file is part of GCC. 6*e4b17023SJohn Marino 7*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under 8*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free 9*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later 10*e4b17023SJohn Marino version. 11*e4b17023SJohn Marino 12*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or 14*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15*e4b17023SJohn Marino for more details. 16*e4b17023SJohn Marino 17*e4b17023SJohn Marino You should have received a copy of the GNU General Public License 18*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see 19*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */ 20*e4b17023SJohn Marino 21*e4b17023SJohn Marino 22*e4b17023SJohn Marino #include "config.h" 23*e4b17023SJohn Marino #include "system.h" 24*e4b17023SJohn Marino #include "coretypes.h" 25*e4b17023SJohn Marino #include "tm.h" 26*e4b17023SJohn Marino #include "flags.h" 27*e4b17023SJohn Marino #include "tree.h" 28*e4b17023SJohn Marino #include "rtl.h" 29*e4b17023SJohn Marino #include "output.h" 30*e4b17023SJohn Marino #include "target.h" 31*e4b17023SJohn Marino #include "dwarf2asm.h" 32*e4b17023SJohn Marino #include "dwarf2.h" 33*e4b17023SJohn Marino #include "splay-tree.h" 34*e4b17023SJohn Marino #include "ggc.h" 35*e4b17023SJohn Marino #include "tm_p.h" 36*e4b17023SJohn Marino 37*e4b17023SJohn Marino 38*e4b17023SJohn Marino /* Output an unaligned integer with the given value and size. Prefer not 39*e4b17023SJohn Marino to print a newline, since the caller may want to add a comment. */ 40*e4b17023SJohn Marino 41*e4b17023SJohn Marino void 42*e4b17023SJohn Marino dw2_assemble_integer (int size, rtx x) 43*e4b17023SJohn Marino { 44*e4b17023SJohn Marino const char *op = integer_asm_op (size, FALSE); 45*e4b17023SJohn Marino 46*e4b17023SJohn Marino if (op) 47*e4b17023SJohn Marino { 48*e4b17023SJohn Marino fputs (op, asm_out_file); 49*e4b17023SJohn Marino if (CONST_INT_P (x)) 50*e4b17023SJohn Marino fprint_whex (asm_out_file, (unsigned HOST_WIDE_INT) INTVAL (x)); 51*e4b17023SJohn Marino else 52*e4b17023SJohn Marino output_addr_const (asm_out_file, x); 53*e4b17023SJohn Marino } 54*e4b17023SJohn Marino else 55*e4b17023SJohn Marino assemble_integer (x, size, BITS_PER_UNIT, 1); 56*e4b17023SJohn Marino } 57*e4b17023SJohn Marino 58*e4b17023SJohn Marino 59*e4b17023SJohn Marino /* Output a value of a given size in target byte order. */ 60*e4b17023SJohn Marino 61*e4b17023SJohn Marino void 62*e4b17023SJohn Marino dw2_asm_output_data_raw (int size, unsigned HOST_WIDE_INT value) 63*e4b17023SJohn Marino { 64*e4b17023SJohn Marino unsigned char bytes[8]; 65*e4b17023SJohn Marino int i; 66*e4b17023SJohn Marino 67*e4b17023SJohn Marino for (i = 0; i < 8; ++i) 68*e4b17023SJohn Marino { 69*e4b17023SJohn Marino bytes[i] = value & 0xff; 70*e4b17023SJohn Marino value >>= 8; 71*e4b17023SJohn Marino } 72*e4b17023SJohn Marino 73*e4b17023SJohn Marino if (BYTES_BIG_ENDIAN) 74*e4b17023SJohn Marino { 75*e4b17023SJohn Marino for (i = size - 1; i > 0; --i) 76*e4b17023SJohn Marino fprintf (asm_out_file, "%#x,", bytes[i]); 77*e4b17023SJohn Marino fprintf (asm_out_file, "%#x", bytes[0]); 78*e4b17023SJohn Marino } 79*e4b17023SJohn Marino else 80*e4b17023SJohn Marino { 81*e4b17023SJohn Marino for (i = 0; i < size - 1; ++i) 82*e4b17023SJohn Marino fprintf (asm_out_file, "%#x,", bytes[i]); 83*e4b17023SJohn Marino fprintf (asm_out_file, "%#x", bytes[i]); 84*e4b17023SJohn Marino } 85*e4b17023SJohn Marino } 86*e4b17023SJohn Marino 87*e4b17023SJohn Marino /* Output an immediate constant in a given SIZE in bytes. */ 88*e4b17023SJohn Marino 89*e4b17023SJohn Marino void 90*e4b17023SJohn Marino dw2_asm_output_data (int size, unsigned HOST_WIDE_INT value, 91*e4b17023SJohn Marino const char *comment, ...) 92*e4b17023SJohn Marino { 93*e4b17023SJohn Marino va_list ap; 94*e4b17023SJohn Marino const char *op = integer_asm_op (size, FALSE); 95*e4b17023SJohn Marino 96*e4b17023SJohn Marino va_start (ap, comment); 97*e4b17023SJohn Marino 98*e4b17023SJohn Marino if (size * 8 < HOST_BITS_PER_WIDE_INT) 99*e4b17023SJohn Marino value &= ~(~(unsigned HOST_WIDE_INT) 0 << (size * 8)); 100*e4b17023SJohn Marino 101*e4b17023SJohn Marino if (op) 102*e4b17023SJohn Marino { 103*e4b17023SJohn Marino fputs (op, asm_out_file); 104*e4b17023SJohn Marino fprint_whex (asm_out_file, value); 105*e4b17023SJohn Marino } 106*e4b17023SJohn Marino else 107*e4b17023SJohn Marino assemble_integer (GEN_INT (value), size, BITS_PER_UNIT, 1); 108*e4b17023SJohn Marino 109*e4b17023SJohn Marino if (flag_debug_asm && comment) 110*e4b17023SJohn Marino { 111*e4b17023SJohn Marino fputs ("\t" ASM_COMMENT_START " ", asm_out_file); 112*e4b17023SJohn Marino vfprintf (asm_out_file, comment, ap); 113*e4b17023SJohn Marino } 114*e4b17023SJohn Marino putc ('\n', asm_out_file); 115*e4b17023SJohn Marino 116*e4b17023SJohn Marino va_end (ap); 117*e4b17023SJohn Marino } 118*e4b17023SJohn Marino 119*e4b17023SJohn Marino /* Output the difference between two symbols in a given size. */ 120*e4b17023SJohn Marino /* ??? There appear to be assemblers that do not like such 121*e4b17023SJohn Marino subtraction, but do support ASM_SET_OP. It's unfortunately 122*e4b17023SJohn Marino impossible to do here, since the ASM_SET_OP for the difference 123*e4b17023SJohn Marino symbol must appear after both symbols are defined. */ 124*e4b17023SJohn Marino 125*e4b17023SJohn Marino void 126*e4b17023SJohn Marino dw2_asm_output_delta (int size, const char *lab1, const char *lab2, 127*e4b17023SJohn Marino const char *comment, ...) 128*e4b17023SJohn Marino { 129*e4b17023SJohn Marino va_list ap; 130*e4b17023SJohn Marino 131*e4b17023SJohn Marino va_start (ap, comment); 132*e4b17023SJohn Marino 133*e4b17023SJohn Marino #ifdef ASM_OUTPUT_DWARF_DELTA 134*e4b17023SJohn Marino ASM_OUTPUT_DWARF_DELTA (asm_out_file, size, lab1, lab2); 135*e4b17023SJohn Marino #else 136*e4b17023SJohn Marino dw2_assemble_integer (size, 137*e4b17023SJohn Marino gen_rtx_MINUS (Pmode, 138*e4b17023SJohn Marino gen_rtx_SYMBOL_REF (Pmode, lab1), 139*e4b17023SJohn Marino gen_rtx_SYMBOL_REF (Pmode, lab2))); 140*e4b17023SJohn Marino #endif 141*e4b17023SJohn Marino if (flag_debug_asm && comment) 142*e4b17023SJohn Marino { 143*e4b17023SJohn Marino fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START); 144*e4b17023SJohn Marino vfprintf (asm_out_file, comment, ap); 145*e4b17023SJohn Marino } 146*e4b17023SJohn Marino fputc ('\n', asm_out_file); 147*e4b17023SJohn Marino 148*e4b17023SJohn Marino va_end (ap); 149*e4b17023SJohn Marino } 150*e4b17023SJohn Marino 151*e4b17023SJohn Marino /* Output the difference between two symbols in instruction units 152*e4b17023SJohn Marino in a given size. */ 153*e4b17023SJohn Marino 154*e4b17023SJohn Marino void 155*e4b17023SJohn Marino dw2_asm_output_vms_delta (int size ATTRIBUTE_UNUSED, 156*e4b17023SJohn Marino const char *lab1, const char *lab2, 157*e4b17023SJohn Marino const char *comment, ...) 158*e4b17023SJohn Marino { 159*e4b17023SJohn Marino va_list ap; 160*e4b17023SJohn Marino 161*e4b17023SJohn Marino va_start (ap, comment); 162*e4b17023SJohn Marino 163*e4b17023SJohn Marino #ifndef ASM_OUTPUT_DWARF_VMS_DELTA 164*e4b17023SJohn Marino /* VMS Delta is only special on ia64-vms, but this funtion also gets 165*e4b17023SJohn Marino called on alpha-vms so it has to do something sane. */ 166*e4b17023SJohn Marino dw2_asm_output_delta (size, lab1, lab2, comment); 167*e4b17023SJohn Marino #else 168*e4b17023SJohn Marino ASM_OUTPUT_DWARF_VMS_DELTA (asm_out_file, size, lab1, lab2); 169*e4b17023SJohn Marino if (flag_debug_asm && comment) 170*e4b17023SJohn Marino { 171*e4b17023SJohn Marino fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START); 172*e4b17023SJohn Marino vfprintf (asm_out_file, comment, ap); 173*e4b17023SJohn Marino } 174*e4b17023SJohn Marino fputc ('\n', asm_out_file); 175*e4b17023SJohn Marino #endif 176*e4b17023SJohn Marino 177*e4b17023SJohn Marino va_end (ap); 178*e4b17023SJohn Marino } 179*e4b17023SJohn Marino 180*e4b17023SJohn Marino /* Output a section-relative reference to a LABEL, which was placed in 181*e4b17023SJohn Marino BASE. In general this can only be done for debugging symbols. 182*e4b17023SJohn Marino E.g. on most targets with the GNU linker, this is accomplished with 183*e4b17023SJohn Marino a direct reference and the knowledge that the debugging section 184*e4b17023SJohn Marino will be placed at VMA 0. Some targets have special relocations for 185*e4b17023SJohn Marino this that we must use. */ 186*e4b17023SJohn Marino 187*e4b17023SJohn Marino void 188*e4b17023SJohn Marino dw2_asm_output_offset (int size, const char *label, 189*e4b17023SJohn Marino section *base ATTRIBUTE_UNUSED, 190*e4b17023SJohn Marino const char *comment, ...) 191*e4b17023SJohn Marino { 192*e4b17023SJohn Marino va_list ap; 193*e4b17023SJohn Marino 194*e4b17023SJohn Marino va_start (ap, comment); 195*e4b17023SJohn Marino 196*e4b17023SJohn Marino #ifdef ASM_OUTPUT_DWARF_OFFSET 197*e4b17023SJohn Marino ASM_OUTPUT_DWARF_OFFSET (asm_out_file, size, label, base); 198*e4b17023SJohn Marino #else 199*e4b17023SJohn Marino dw2_assemble_integer (size, gen_rtx_SYMBOL_REF (Pmode, label)); 200*e4b17023SJohn Marino #endif 201*e4b17023SJohn Marino 202*e4b17023SJohn Marino if (flag_debug_asm && comment) 203*e4b17023SJohn Marino { 204*e4b17023SJohn Marino fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START); 205*e4b17023SJohn Marino vfprintf (asm_out_file, comment, ap); 206*e4b17023SJohn Marino } 207*e4b17023SJohn Marino fputc ('\n', asm_out_file); 208*e4b17023SJohn Marino 209*e4b17023SJohn Marino va_end (ap); 210*e4b17023SJohn Marino } 211*e4b17023SJohn Marino 212*e4b17023SJohn Marino #if 0 213*e4b17023SJohn Marino 214*e4b17023SJohn Marino /* Output a self-relative reference to a label, possibly in a 215*e4b17023SJohn Marino different section or object file. */ 216*e4b17023SJohn Marino 217*e4b17023SJohn Marino void 218*e4b17023SJohn Marino dw2_asm_output_pcrel (int size ATTRIBUTE_UNUSED, 219*e4b17023SJohn Marino const char *label ATTRIBUTE_UNUSED, 220*e4b17023SJohn Marino const char *comment, ...) 221*e4b17023SJohn Marino { 222*e4b17023SJohn Marino va_list ap; 223*e4b17023SJohn Marino 224*e4b17023SJohn Marino va_start (ap, comment); 225*e4b17023SJohn Marino 226*e4b17023SJohn Marino #ifdef ASM_OUTPUT_DWARF_PCREL 227*e4b17023SJohn Marino ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, label); 228*e4b17023SJohn Marino #else 229*e4b17023SJohn Marino dw2_assemble_integer (size, 230*e4b17023SJohn Marino gen_rtx_MINUS (Pmode, 231*e4b17023SJohn Marino gen_rtx_SYMBOL_REF (Pmode, label), 232*e4b17023SJohn Marino pc_rtx)); 233*e4b17023SJohn Marino #endif 234*e4b17023SJohn Marino 235*e4b17023SJohn Marino if (flag_debug_asm && comment) 236*e4b17023SJohn Marino { 237*e4b17023SJohn Marino fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START); 238*e4b17023SJohn Marino vfprintf (asm_out_file, comment, ap); 239*e4b17023SJohn Marino } 240*e4b17023SJohn Marino fputc ('\n', asm_out_file); 241*e4b17023SJohn Marino 242*e4b17023SJohn Marino va_end (ap); 243*e4b17023SJohn Marino } 244*e4b17023SJohn Marino #endif /* 0 */ 245*e4b17023SJohn Marino 246*e4b17023SJohn Marino /* Output an absolute reference to a label. */ 247*e4b17023SJohn Marino 248*e4b17023SJohn Marino void 249*e4b17023SJohn Marino dw2_asm_output_addr (int size, const char *label, 250*e4b17023SJohn Marino const char *comment, ...) 251*e4b17023SJohn Marino { 252*e4b17023SJohn Marino va_list ap; 253*e4b17023SJohn Marino 254*e4b17023SJohn Marino va_start (ap, comment); 255*e4b17023SJohn Marino 256*e4b17023SJohn Marino dw2_assemble_integer (size, gen_rtx_SYMBOL_REF (Pmode, label)); 257*e4b17023SJohn Marino 258*e4b17023SJohn Marino if (flag_debug_asm && comment) 259*e4b17023SJohn Marino { 260*e4b17023SJohn Marino fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START); 261*e4b17023SJohn Marino vfprintf (asm_out_file, comment, ap); 262*e4b17023SJohn Marino } 263*e4b17023SJohn Marino fputc ('\n', asm_out_file); 264*e4b17023SJohn Marino 265*e4b17023SJohn Marino va_end (ap); 266*e4b17023SJohn Marino } 267*e4b17023SJohn Marino 268*e4b17023SJohn Marino /* Similar, but use an RTX expression instead of a text label. */ 269*e4b17023SJohn Marino 270*e4b17023SJohn Marino void 271*e4b17023SJohn Marino dw2_asm_output_addr_rtx (int size, rtx addr, 272*e4b17023SJohn Marino const char *comment, ...) 273*e4b17023SJohn Marino { 274*e4b17023SJohn Marino va_list ap; 275*e4b17023SJohn Marino 276*e4b17023SJohn Marino va_start (ap, comment); 277*e4b17023SJohn Marino 278*e4b17023SJohn Marino dw2_assemble_integer (size, addr); 279*e4b17023SJohn Marino 280*e4b17023SJohn Marino if (flag_debug_asm && comment) 281*e4b17023SJohn Marino { 282*e4b17023SJohn Marino fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START); 283*e4b17023SJohn Marino vfprintf (asm_out_file, comment, ap); 284*e4b17023SJohn Marino } 285*e4b17023SJohn Marino fputc ('\n', asm_out_file); 286*e4b17023SJohn Marino 287*e4b17023SJohn Marino va_end (ap); 288*e4b17023SJohn Marino } 289*e4b17023SJohn Marino 290*e4b17023SJohn Marino /* Output the first ORIG_LEN characters of STR as a string. 291*e4b17023SJohn Marino If ORIG_LEN is equal to -1, ignore this parameter and output 292*e4b17023SJohn Marino the entire STR instead. 293*e4b17023SJohn Marino If COMMENT is not NULL and comments in the debug information 294*e4b17023SJohn Marino have been requested by the user, append the given COMMENT 295*e4b17023SJohn Marino to the generated output. */ 296*e4b17023SJohn Marino 297*e4b17023SJohn Marino void 298*e4b17023SJohn Marino dw2_asm_output_nstring (const char *str, size_t orig_len, 299*e4b17023SJohn Marino const char *comment, ...) 300*e4b17023SJohn Marino { 301*e4b17023SJohn Marino size_t i, len; 302*e4b17023SJohn Marino va_list ap; 303*e4b17023SJohn Marino 304*e4b17023SJohn Marino va_start (ap, comment); 305*e4b17023SJohn Marino 306*e4b17023SJohn Marino len = orig_len; 307*e4b17023SJohn Marino 308*e4b17023SJohn Marino if (len == (size_t) -1) 309*e4b17023SJohn Marino len = strlen (str); 310*e4b17023SJohn Marino 311*e4b17023SJohn Marino if (flag_debug_asm && comment) 312*e4b17023SJohn Marino { 313*e4b17023SJohn Marino fputs ("\t.ascii \"", asm_out_file); 314*e4b17023SJohn Marino for (i = 0; i < len; i++) 315*e4b17023SJohn Marino { 316*e4b17023SJohn Marino int c = str[i]; 317*e4b17023SJohn Marino if (c == '\"' || c == '\\') 318*e4b17023SJohn Marino fputc ('\\', asm_out_file); 319*e4b17023SJohn Marino if (ISPRINT(c)) 320*e4b17023SJohn Marino fputc (c, asm_out_file); 321*e4b17023SJohn Marino else 322*e4b17023SJohn Marino fprintf (asm_out_file, "\\%o", c); 323*e4b17023SJohn Marino } 324*e4b17023SJohn Marino fprintf (asm_out_file, "\\0\"\t%s ", ASM_COMMENT_START); 325*e4b17023SJohn Marino vfprintf (asm_out_file, comment, ap); 326*e4b17023SJohn Marino fputc ('\n', asm_out_file); 327*e4b17023SJohn Marino } 328*e4b17023SJohn Marino else 329*e4b17023SJohn Marino { 330*e4b17023SJohn Marino /* If an explicit length was given, we can't assume there 331*e4b17023SJohn Marino is a null termination in the string buffer. */ 332*e4b17023SJohn Marino if (orig_len == (size_t) -1) 333*e4b17023SJohn Marino len += 1; 334*e4b17023SJohn Marino ASM_OUTPUT_ASCII (asm_out_file, str, len); 335*e4b17023SJohn Marino if (orig_len != (size_t) -1) 336*e4b17023SJohn Marino assemble_integer (const0_rtx, 1, BITS_PER_UNIT, 1); 337*e4b17023SJohn Marino } 338*e4b17023SJohn Marino 339*e4b17023SJohn Marino va_end (ap); 340*e4b17023SJohn Marino } 341*e4b17023SJohn Marino 342*e4b17023SJohn Marino 343*e4b17023SJohn Marino /* Return the size of an unsigned LEB128 quantity. */ 344*e4b17023SJohn Marino 345*e4b17023SJohn Marino int 346*e4b17023SJohn Marino size_of_uleb128 (unsigned HOST_WIDE_INT value) 347*e4b17023SJohn Marino { 348*e4b17023SJohn Marino int size = 0; 349*e4b17023SJohn Marino 350*e4b17023SJohn Marino do 351*e4b17023SJohn Marino { 352*e4b17023SJohn Marino value >>= 7; 353*e4b17023SJohn Marino size += 1; 354*e4b17023SJohn Marino } 355*e4b17023SJohn Marino while (value != 0); 356*e4b17023SJohn Marino 357*e4b17023SJohn Marino return size; 358*e4b17023SJohn Marino } 359*e4b17023SJohn Marino 360*e4b17023SJohn Marino /* Return the size of a signed LEB128 quantity. */ 361*e4b17023SJohn Marino 362*e4b17023SJohn Marino int 363*e4b17023SJohn Marino size_of_sleb128 (HOST_WIDE_INT value) 364*e4b17023SJohn Marino { 365*e4b17023SJohn Marino int size = 0, byte; 366*e4b17023SJohn Marino 367*e4b17023SJohn Marino do 368*e4b17023SJohn Marino { 369*e4b17023SJohn Marino byte = (value & 0x7f); 370*e4b17023SJohn Marino value >>= 7; 371*e4b17023SJohn Marino size += 1; 372*e4b17023SJohn Marino } 373*e4b17023SJohn Marino while (!((value == 0 && (byte & 0x40) == 0) 374*e4b17023SJohn Marino || (value == -1 && (byte & 0x40) != 0))); 375*e4b17023SJohn Marino 376*e4b17023SJohn Marino return size; 377*e4b17023SJohn Marino } 378*e4b17023SJohn Marino 379*e4b17023SJohn Marino /* Given an encoding, return the number of bytes the format occupies. 380*e4b17023SJohn Marino This is only defined for fixed-size encodings, and so does not 381*e4b17023SJohn Marino include leb128. */ 382*e4b17023SJohn Marino 383*e4b17023SJohn Marino int 384*e4b17023SJohn Marino size_of_encoded_value (int encoding) 385*e4b17023SJohn Marino { 386*e4b17023SJohn Marino if (encoding == DW_EH_PE_omit) 387*e4b17023SJohn Marino return 0; 388*e4b17023SJohn Marino 389*e4b17023SJohn Marino switch (encoding & 0x07) 390*e4b17023SJohn Marino { 391*e4b17023SJohn Marino case DW_EH_PE_absptr: 392*e4b17023SJohn Marino return POINTER_SIZE / BITS_PER_UNIT; 393*e4b17023SJohn Marino case DW_EH_PE_udata2: 394*e4b17023SJohn Marino return 2; 395*e4b17023SJohn Marino case DW_EH_PE_udata4: 396*e4b17023SJohn Marino return 4; 397*e4b17023SJohn Marino case DW_EH_PE_udata8: 398*e4b17023SJohn Marino return 8; 399*e4b17023SJohn Marino default: 400*e4b17023SJohn Marino gcc_unreachable (); 401*e4b17023SJohn Marino } 402*e4b17023SJohn Marino } 403*e4b17023SJohn Marino 404*e4b17023SJohn Marino /* Yield a name for a given pointer encoding. */ 405*e4b17023SJohn Marino 406*e4b17023SJohn Marino const char * 407*e4b17023SJohn Marino eh_data_format_name (int format) 408*e4b17023SJohn Marino { 409*e4b17023SJohn Marino #if HAVE_DESIGNATED_INITIALIZERS 410*e4b17023SJohn Marino #define S(p, v) [p] = v, 411*e4b17023SJohn Marino #else 412*e4b17023SJohn Marino #define S(p, v) case p: return v; 413*e4b17023SJohn Marino #endif 414*e4b17023SJohn Marino 415*e4b17023SJohn Marino #if HAVE_DESIGNATED_INITIALIZERS 416*e4b17023SJohn Marino __extension__ static const char * const format_names[256] = { 417*e4b17023SJohn Marino #else 418*e4b17023SJohn Marino switch (format) { 419*e4b17023SJohn Marino #endif 420*e4b17023SJohn Marino 421*e4b17023SJohn Marino S(DW_EH_PE_absptr, "absolute") 422*e4b17023SJohn Marino S(DW_EH_PE_omit, "omit") 423*e4b17023SJohn Marino S(DW_EH_PE_aligned, "aligned absolute") 424*e4b17023SJohn Marino 425*e4b17023SJohn Marino S(DW_EH_PE_uleb128, "uleb128") 426*e4b17023SJohn Marino S(DW_EH_PE_udata2, "udata2") 427*e4b17023SJohn Marino S(DW_EH_PE_udata4, "udata4") 428*e4b17023SJohn Marino S(DW_EH_PE_udata8, "udata8") 429*e4b17023SJohn Marino S(DW_EH_PE_sleb128, "sleb128") 430*e4b17023SJohn Marino S(DW_EH_PE_sdata2, "sdata2") 431*e4b17023SJohn Marino S(DW_EH_PE_sdata4, "sdata4") 432*e4b17023SJohn Marino S(DW_EH_PE_sdata8, "sdata8") 433*e4b17023SJohn Marino 434*e4b17023SJohn Marino S(DW_EH_PE_absptr | DW_EH_PE_pcrel, "pcrel") 435*e4b17023SJohn Marino S(DW_EH_PE_uleb128 | DW_EH_PE_pcrel, "pcrel uleb128") 436*e4b17023SJohn Marino S(DW_EH_PE_udata2 | DW_EH_PE_pcrel, "pcrel udata2") 437*e4b17023SJohn Marino S(DW_EH_PE_udata4 | DW_EH_PE_pcrel, "pcrel udata4") 438*e4b17023SJohn Marino S(DW_EH_PE_udata8 | DW_EH_PE_pcrel, "pcrel udata8") 439*e4b17023SJohn Marino S(DW_EH_PE_sleb128 | DW_EH_PE_pcrel, "pcrel sleb128") 440*e4b17023SJohn Marino S(DW_EH_PE_sdata2 | DW_EH_PE_pcrel, "pcrel sdata2") 441*e4b17023SJohn Marino S(DW_EH_PE_sdata4 | DW_EH_PE_pcrel, "pcrel sdata4") 442*e4b17023SJohn Marino S(DW_EH_PE_sdata8 | DW_EH_PE_pcrel, "pcrel sdata8") 443*e4b17023SJohn Marino 444*e4b17023SJohn Marino S(DW_EH_PE_absptr | DW_EH_PE_textrel, "textrel") 445*e4b17023SJohn Marino S(DW_EH_PE_uleb128 | DW_EH_PE_textrel, "textrel uleb128") 446*e4b17023SJohn Marino S(DW_EH_PE_udata2 | DW_EH_PE_textrel, "textrel udata2") 447*e4b17023SJohn Marino S(DW_EH_PE_udata4 | DW_EH_PE_textrel, "textrel udata4") 448*e4b17023SJohn Marino S(DW_EH_PE_udata8 | DW_EH_PE_textrel, "textrel udata8") 449*e4b17023SJohn Marino S(DW_EH_PE_sleb128 | DW_EH_PE_textrel, "textrel sleb128") 450*e4b17023SJohn Marino S(DW_EH_PE_sdata2 | DW_EH_PE_textrel, "textrel sdata2") 451*e4b17023SJohn Marino S(DW_EH_PE_sdata4 | DW_EH_PE_textrel, "textrel sdata4") 452*e4b17023SJohn Marino S(DW_EH_PE_sdata8 | DW_EH_PE_textrel, "textrel sdata8") 453*e4b17023SJohn Marino 454*e4b17023SJohn Marino S(DW_EH_PE_absptr | DW_EH_PE_datarel, "datarel") 455*e4b17023SJohn Marino S(DW_EH_PE_uleb128 | DW_EH_PE_datarel, "datarel uleb128") 456*e4b17023SJohn Marino S(DW_EH_PE_udata2 | DW_EH_PE_datarel, "datarel udata2") 457*e4b17023SJohn Marino S(DW_EH_PE_udata4 | DW_EH_PE_datarel, "datarel udata4") 458*e4b17023SJohn Marino S(DW_EH_PE_udata8 | DW_EH_PE_datarel, "datarel udata8") 459*e4b17023SJohn Marino S(DW_EH_PE_sleb128 | DW_EH_PE_datarel, "datarel sleb128") 460*e4b17023SJohn Marino S(DW_EH_PE_sdata2 | DW_EH_PE_datarel, "datarel sdata2") 461*e4b17023SJohn Marino S(DW_EH_PE_sdata4 | DW_EH_PE_datarel, "datarel sdata4") 462*e4b17023SJohn Marino S(DW_EH_PE_sdata8 | DW_EH_PE_datarel, "datarel sdata8") 463*e4b17023SJohn Marino 464*e4b17023SJohn Marino S(DW_EH_PE_absptr | DW_EH_PE_funcrel, "funcrel") 465*e4b17023SJohn Marino S(DW_EH_PE_uleb128 | DW_EH_PE_funcrel, "funcrel uleb128") 466*e4b17023SJohn Marino S(DW_EH_PE_udata2 | DW_EH_PE_funcrel, "funcrel udata2") 467*e4b17023SJohn Marino S(DW_EH_PE_udata4 | DW_EH_PE_funcrel, "funcrel udata4") 468*e4b17023SJohn Marino S(DW_EH_PE_udata8 | DW_EH_PE_funcrel, "funcrel udata8") 469*e4b17023SJohn Marino S(DW_EH_PE_sleb128 | DW_EH_PE_funcrel, "funcrel sleb128") 470*e4b17023SJohn Marino S(DW_EH_PE_sdata2 | DW_EH_PE_funcrel, "funcrel sdata2") 471*e4b17023SJohn Marino S(DW_EH_PE_sdata4 | DW_EH_PE_funcrel, "funcrel sdata4") 472*e4b17023SJohn Marino S(DW_EH_PE_sdata8 | DW_EH_PE_funcrel, "funcrel sdata8") 473*e4b17023SJohn Marino 474*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_absptr, "indirect absolute") 475*e4b17023SJohn Marino 476*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_pcrel, 477*e4b17023SJohn Marino "indirect pcrel") 478*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_pcrel, 479*e4b17023SJohn Marino "indirect pcrel uleb128") 480*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_pcrel, 481*e4b17023SJohn Marino "indirect pcrel udata2") 482*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_pcrel, 483*e4b17023SJohn Marino "indirect pcrel udata4") 484*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_pcrel, 485*e4b17023SJohn Marino "indirect pcrel udata8") 486*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_pcrel, 487*e4b17023SJohn Marino "indirect pcrel sleb128") 488*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_pcrel, 489*e4b17023SJohn Marino "indirect pcrel sdata2") 490*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_pcrel, 491*e4b17023SJohn Marino "indirect pcrel sdata4") 492*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_pcrel, 493*e4b17023SJohn Marino "indirect pcrel sdata8") 494*e4b17023SJohn Marino 495*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_textrel, 496*e4b17023SJohn Marino "indirect textrel") 497*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_textrel, 498*e4b17023SJohn Marino "indirect textrel uleb128") 499*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_textrel, 500*e4b17023SJohn Marino "indirect textrel udata2") 501*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_textrel, 502*e4b17023SJohn Marino "indirect textrel udata4") 503*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_textrel, 504*e4b17023SJohn Marino "indirect textrel udata8") 505*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_textrel, 506*e4b17023SJohn Marino "indirect textrel sleb128") 507*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_textrel, 508*e4b17023SJohn Marino "indirect textrel sdata2") 509*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_textrel, 510*e4b17023SJohn Marino "indirect textrel sdata4") 511*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_textrel, 512*e4b17023SJohn Marino "indirect textrel sdata8") 513*e4b17023SJohn Marino 514*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_datarel, 515*e4b17023SJohn Marino "indirect datarel") 516*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_datarel, 517*e4b17023SJohn Marino "indirect datarel uleb128") 518*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_datarel, 519*e4b17023SJohn Marino "indirect datarel udata2") 520*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_datarel, 521*e4b17023SJohn Marino "indirect datarel udata4") 522*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_datarel, 523*e4b17023SJohn Marino "indirect datarel udata8") 524*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_datarel, 525*e4b17023SJohn Marino "indirect datarel sleb128") 526*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_datarel, 527*e4b17023SJohn Marino "indirect datarel sdata2") 528*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_datarel, 529*e4b17023SJohn Marino "indirect datarel sdata4") 530*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_datarel, 531*e4b17023SJohn Marino "indirect datarel sdata8") 532*e4b17023SJohn Marino 533*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_funcrel, 534*e4b17023SJohn Marino "indirect funcrel") 535*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_funcrel, 536*e4b17023SJohn Marino "indirect funcrel uleb128") 537*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_funcrel, 538*e4b17023SJohn Marino "indirect funcrel udata2") 539*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_funcrel, 540*e4b17023SJohn Marino "indirect funcrel udata4") 541*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_funcrel, 542*e4b17023SJohn Marino "indirect funcrel udata8") 543*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_funcrel, 544*e4b17023SJohn Marino "indirect funcrel sleb128") 545*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_funcrel, 546*e4b17023SJohn Marino "indirect funcrel sdata2") 547*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_funcrel, 548*e4b17023SJohn Marino "indirect funcrel sdata4") 549*e4b17023SJohn Marino S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_funcrel, 550*e4b17023SJohn Marino "indirect funcrel sdata8") 551*e4b17023SJohn Marino 552*e4b17023SJohn Marino #if HAVE_DESIGNATED_INITIALIZERS 553*e4b17023SJohn Marino }; 554*e4b17023SJohn Marino 555*e4b17023SJohn Marino gcc_assert (format >= 0 && format < 0x100 && format_names[format]); 556*e4b17023SJohn Marino 557*e4b17023SJohn Marino return format_names[format]; 558*e4b17023SJohn Marino #else 559*e4b17023SJohn Marino } 560*e4b17023SJohn Marino gcc_unreachable (); 561*e4b17023SJohn Marino #endif 562*e4b17023SJohn Marino } 563*e4b17023SJohn Marino 564*e4b17023SJohn Marino /* Output an unsigned LEB128 quantity, but only the byte values. */ 565*e4b17023SJohn Marino 566*e4b17023SJohn Marino void 567*e4b17023SJohn Marino dw2_asm_output_data_uleb128_raw (unsigned HOST_WIDE_INT value) 568*e4b17023SJohn Marino { 569*e4b17023SJohn Marino while (1) 570*e4b17023SJohn Marino { 571*e4b17023SJohn Marino int byte = (value & 0x7f); 572*e4b17023SJohn Marino value >>= 7; 573*e4b17023SJohn Marino if (value != 0) 574*e4b17023SJohn Marino /* More bytes to follow. */ 575*e4b17023SJohn Marino byte |= 0x80; 576*e4b17023SJohn Marino 577*e4b17023SJohn Marino fprintf (asm_out_file, "%#x", byte); 578*e4b17023SJohn Marino if (value == 0) 579*e4b17023SJohn Marino break; 580*e4b17023SJohn Marino fputc (',', asm_out_file); 581*e4b17023SJohn Marino } 582*e4b17023SJohn Marino } 583*e4b17023SJohn Marino 584*e4b17023SJohn Marino /* Output an unsigned LEB128 quantity. */ 585*e4b17023SJohn Marino 586*e4b17023SJohn Marino void 587*e4b17023SJohn Marino dw2_asm_output_data_uleb128 (unsigned HOST_WIDE_INT value, 588*e4b17023SJohn Marino const char *comment, ...) 589*e4b17023SJohn Marino { 590*e4b17023SJohn Marino va_list ap; 591*e4b17023SJohn Marino 592*e4b17023SJohn Marino va_start (ap, comment); 593*e4b17023SJohn Marino 594*e4b17023SJohn Marino #ifdef HAVE_AS_LEB128 595*e4b17023SJohn Marino fputs ("\t.uleb128 ", asm_out_file); 596*e4b17023SJohn Marino fprint_whex (asm_out_file, value); 597*e4b17023SJohn Marino 598*e4b17023SJohn Marino if (flag_debug_asm && comment) 599*e4b17023SJohn Marino { 600*e4b17023SJohn Marino fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START); 601*e4b17023SJohn Marino vfprintf (asm_out_file, comment, ap); 602*e4b17023SJohn Marino } 603*e4b17023SJohn Marino #else 604*e4b17023SJohn Marino { 605*e4b17023SJohn Marino unsigned HOST_WIDE_INT work = value; 606*e4b17023SJohn Marino const char *byte_op = targetm.asm_out.byte_op; 607*e4b17023SJohn Marino 608*e4b17023SJohn Marino if (byte_op) 609*e4b17023SJohn Marino fputs (byte_op, asm_out_file); 610*e4b17023SJohn Marino do 611*e4b17023SJohn Marino { 612*e4b17023SJohn Marino int byte = (work & 0x7f); 613*e4b17023SJohn Marino work >>= 7; 614*e4b17023SJohn Marino if (work != 0) 615*e4b17023SJohn Marino /* More bytes to follow. */ 616*e4b17023SJohn Marino byte |= 0x80; 617*e4b17023SJohn Marino 618*e4b17023SJohn Marino if (byte_op) 619*e4b17023SJohn Marino { 620*e4b17023SJohn Marino fprintf (asm_out_file, "%#x", byte); 621*e4b17023SJohn Marino if (work != 0) 622*e4b17023SJohn Marino fputc (',', asm_out_file); 623*e4b17023SJohn Marino } 624*e4b17023SJohn Marino else 625*e4b17023SJohn Marino assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1); 626*e4b17023SJohn Marino } 627*e4b17023SJohn Marino while (work != 0); 628*e4b17023SJohn Marino 629*e4b17023SJohn Marino if (flag_debug_asm) 630*e4b17023SJohn Marino { 631*e4b17023SJohn Marino fprintf (asm_out_file, "\t%s uleb128 " HOST_WIDE_INT_PRINT_HEX, 632*e4b17023SJohn Marino ASM_COMMENT_START, value); 633*e4b17023SJohn Marino if (comment) 634*e4b17023SJohn Marino { 635*e4b17023SJohn Marino fputs ("; ", asm_out_file); 636*e4b17023SJohn Marino vfprintf (asm_out_file, comment, ap); 637*e4b17023SJohn Marino } 638*e4b17023SJohn Marino } 639*e4b17023SJohn Marino } 640*e4b17023SJohn Marino #endif 641*e4b17023SJohn Marino putc ('\n', asm_out_file); 642*e4b17023SJohn Marino 643*e4b17023SJohn Marino va_end (ap); 644*e4b17023SJohn Marino } 645*e4b17023SJohn Marino 646*e4b17023SJohn Marino /* Output an signed LEB128 quantity, but only the byte values. */ 647*e4b17023SJohn Marino 648*e4b17023SJohn Marino void 649*e4b17023SJohn Marino dw2_asm_output_data_sleb128_raw (HOST_WIDE_INT value) 650*e4b17023SJohn Marino { 651*e4b17023SJohn Marino int byte, more; 652*e4b17023SJohn Marino 653*e4b17023SJohn Marino while (1) 654*e4b17023SJohn Marino { 655*e4b17023SJohn Marino byte = (value & 0x7f); 656*e4b17023SJohn Marino value >>= 7; 657*e4b17023SJohn Marino more = !((value == 0 && (byte & 0x40) == 0) 658*e4b17023SJohn Marino || (value == -1 && (byte & 0x40) != 0)); 659*e4b17023SJohn Marino if (more) 660*e4b17023SJohn Marino byte |= 0x80; 661*e4b17023SJohn Marino 662*e4b17023SJohn Marino fprintf (asm_out_file, "%#x", byte); 663*e4b17023SJohn Marino if (!more) 664*e4b17023SJohn Marino break; 665*e4b17023SJohn Marino fputc (',', asm_out_file); 666*e4b17023SJohn Marino } 667*e4b17023SJohn Marino } 668*e4b17023SJohn Marino 669*e4b17023SJohn Marino /* Output a signed LEB128 quantity. */ 670*e4b17023SJohn Marino 671*e4b17023SJohn Marino void 672*e4b17023SJohn Marino dw2_asm_output_data_sleb128 (HOST_WIDE_INT value, 673*e4b17023SJohn Marino const char *comment, ...) 674*e4b17023SJohn Marino { 675*e4b17023SJohn Marino va_list ap; 676*e4b17023SJohn Marino 677*e4b17023SJohn Marino va_start (ap, comment); 678*e4b17023SJohn Marino 679*e4b17023SJohn Marino #ifdef HAVE_AS_LEB128 680*e4b17023SJohn Marino fprintf (asm_out_file, "\t.sleb128 " HOST_WIDE_INT_PRINT_DEC, value); 681*e4b17023SJohn Marino 682*e4b17023SJohn Marino if (flag_debug_asm && comment) 683*e4b17023SJohn Marino { 684*e4b17023SJohn Marino fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START); 685*e4b17023SJohn Marino vfprintf (asm_out_file, comment, ap); 686*e4b17023SJohn Marino } 687*e4b17023SJohn Marino #else 688*e4b17023SJohn Marino { 689*e4b17023SJohn Marino HOST_WIDE_INT work = value; 690*e4b17023SJohn Marino int more, byte; 691*e4b17023SJohn Marino const char *byte_op = targetm.asm_out.byte_op; 692*e4b17023SJohn Marino 693*e4b17023SJohn Marino if (byte_op) 694*e4b17023SJohn Marino fputs (byte_op, asm_out_file); 695*e4b17023SJohn Marino do 696*e4b17023SJohn Marino { 697*e4b17023SJohn Marino byte = (work & 0x7f); 698*e4b17023SJohn Marino /* arithmetic shift */ 699*e4b17023SJohn Marino work >>= 7; 700*e4b17023SJohn Marino more = !((work == 0 && (byte & 0x40) == 0) 701*e4b17023SJohn Marino || (work == -1 && (byte & 0x40) != 0)); 702*e4b17023SJohn Marino if (more) 703*e4b17023SJohn Marino byte |= 0x80; 704*e4b17023SJohn Marino 705*e4b17023SJohn Marino if (byte_op) 706*e4b17023SJohn Marino { 707*e4b17023SJohn Marino fprintf (asm_out_file, "%#x", byte); 708*e4b17023SJohn Marino if (more) 709*e4b17023SJohn Marino fputc (',', asm_out_file); 710*e4b17023SJohn Marino } 711*e4b17023SJohn Marino else 712*e4b17023SJohn Marino assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1); 713*e4b17023SJohn Marino } 714*e4b17023SJohn Marino while (more); 715*e4b17023SJohn Marino 716*e4b17023SJohn Marino if (flag_debug_asm) 717*e4b17023SJohn Marino { 718*e4b17023SJohn Marino fprintf (asm_out_file, "\t%s sleb128 " HOST_WIDE_INT_PRINT_DEC, 719*e4b17023SJohn Marino ASM_COMMENT_START, value); 720*e4b17023SJohn Marino if (comment) 721*e4b17023SJohn Marino { 722*e4b17023SJohn Marino fputs ("; ", asm_out_file); 723*e4b17023SJohn Marino vfprintf (asm_out_file, comment, ap); 724*e4b17023SJohn Marino } 725*e4b17023SJohn Marino } 726*e4b17023SJohn Marino } 727*e4b17023SJohn Marino #endif 728*e4b17023SJohn Marino fputc ('\n', asm_out_file); 729*e4b17023SJohn Marino 730*e4b17023SJohn Marino va_end (ap); 731*e4b17023SJohn Marino } 732*e4b17023SJohn Marino 733*e4b17023SJohn Marino void 734*e4b17023SJohn Marino dw2_asm_output_delta_uleb128 (const char *lab1 ATTRIBUTE_UNUSED, 735*e4b17023SJohn Marino const char *lab2 ATTRIBUTE_UNUSED, 736*e4b17023SJohn Marino const char *comment, ...) 737*e4b17023SJohn Marino { 738*e4b17023SJohn Marino va_list ap; 739*e4b17023SJohn Marino 740*e4b17023SJohn Marino va_start (ap, comment); 741*e4b17023SJohn Marino 742*e4b17023SJohn Marino #ifdef HAVE_AS_LEB128 743*e4b17023SJohn Marino fputs ("\t.uleb128 ", asm_out_file); 744*e4b17023SJohn Marino assemble_name (asm_out_file, lab1); 745*e4b17023SJohn Marino putc ('-', asm_out_file); 746*e4b17023SJohn Marino assemble_name (asm_out_file, lab2); 747*e4b17023SJohn Marino #else 748*e4b17023SJohn Marino gcc_unreachable (); 749*e4b17023SJohn Marino #endif 750*e4b17023SJohn Marino 751*e4b17023SJohn Marino if (flag_debug_asm && comment) 752*e4b17023SJohn Marino { 753*e4b17023SJohn Marino fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START); 754*e4b17023SJohn Marino vfprintf (asm_out_file, comment, ap); 755*e4b17023SJohn Marino } 756*e4b17023SJohn Marino fputc ('\n', asm_out_file); 757*e4b17023SJohn Marino 758*e4b17023SJohn Marino va_end (ap); 759*e4b17023SJohn Marino } 760*e4b17023SJohn Marino 761*e4b17023SJohn Marino #if 0 762*e4b17023SJohn Marino 763*e4b17023SJohn Marino void 764*e4b17023SJohn Marino dw2_asm_output_delta_sleb128 (const char *lab1 ATTRIBUTE_UNUSED, 765*e4b17023SJohn Marino const char *lab2 ATTRIBUTE_UNUSED, 766*e4b17023SJohn Marino const char *comment, ...) 767*e4b17023SJohn Marino { 768*e4b17023SJohn Marino va_list ap; 769*e4b17023SJohn Marino 770*e4b17023SJohn Marino va_start (ap, comment); 771*e4b17023SJohn Marino 772*e4b17023SJohn Marino #ifdef HAVE_AS_LEB128 773*e4b17023SJohn Marino fputs ("\t.sleb128 ", asm_out_file); 774*e4b17023SJohn Marino assemble_name (asm_out_file, lab1); 775*e4b17023SJohn Marino putc ('-', asm_out_file); 776*e4b17023SJohn Marino assemble_name (asm_out_file, lab2); 777*e4b17023SJohn Marino #else 778*e4b17023SJohn Marino gcc_unreachable (); 779*e4b17023SJohn Marino #endif 780*e4b17023SJohn Marino 781*e4b17023SJohn Marino if (flag_debug_asm && comment) 782*e4b17023SJohn Marino { 783*e4b17023SJohn Marino fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START); 784*e4b17023SJohn Marino vfprintf (asm_out_file, comment, ap); 785*e4b17023SJohn Marino } 786*e4b17023SJohn Marino fputc ('\n', asm_out_file); 787*e4b17023SJohn Marino 788*e4b17023SJohn Marino va_end (ap); 789*e4b17023SJohn Marino } 790*e4b17023SJohn Marino #endif /* 0 */ 791*e4b17023SJohn Marino 792*e4b17023SJohn Marino static int dw2_output_indirect_constant_1 (splay_tree_node, void *); 793*e4b17023SJohn Marino 794*e4b17023SJohn Marino static GTY((param1_is (char *), param2_is (tree))) splay_tree indirect_pool; 795*e4b17023SJohn Marino 796*e4b17023SJohn Marino static GTY(()) int dw2_const_labelno; 797*e4b17023SJohn Marino 798*e4b17023SJohn Marino #if defined(HAVE_GAS_HIDDEN) 799*e4b17023SJohn Marino # define USE_LINKONCE_INDIRECT (SUPPORTS_ONE_ONLY) 800*e4b17023SJohn Marino #else 801*e4b17023SJohn Marino # define USE_LINKONCE_INDIRECT 0 802*e4b17023SJohn Marino #endif 803*e4b17023SJohn Marino 804*e4b17023SJohn Marino /* Comparison function for a splay tree in which the keys are strings. 805*e4b17023SJohn Marino K1 and K2 have the dynamic type "const char *". Returns <0, 0, or 806*e4b17023SJohn Marino >0 to indicate whether K1 is less than, equal to, or greater than 807*e4b17023SJohn Marino K2, respectively. */ 808*e4b17023SJohn Marino 809*e4b17023SJohn Marino static int 810*e4b17023SJohn Marino splay_tree_compare_strings (splay_tree_key k1, splay_tree_key k2) 811*e4b17023SJohn Marino { 812*e4b17023SJohn Marino const char *s1 = (const char *)k1; 813*e4b17023SJohn Marino const char *s2 = (const char *)k2; 814*e4b17023SJohn Marino int ret; 815*e4b17023SJohn Marino 816*e4b17023SJohn Marino if (s1 == s2) 817*e4b17023SJohn Marino return 0; 818*e4b17023SJohn Marino 819*e4b17023SJohn Marino ret = strcmp (s1, s2); 820*e4b17023SJohn Marino 821*e4b17023SJohn Marino /* The strings are always those from IDENTIFIER_NODEs, and, 822*e4b17023SJohn Marino therefore, we should never have two copies of the same 823*e4b17023SJohn Marino string. */ 824*e4b17023SJohn Marino gcc_assert (ret); 825*e4b17023SJohn Marino 826*e4b17023SJohn Marino return ret; 827*e4b17023SJohn Marino } 828*e4b17023SJohn Marino 829*e4b17023SJohn Marino /* Put X, a SYMBOL_REF, in memory. Return a SYMBOL_REF to the allocated 830*e4b17023SJohn Marino memory. Differs from force_const_mem in that a single pool is used for 831*e4b17023SJohn Marino the entire unit of translation, and the memory is not guaranteed to be 832*e4b17023SJohn Marino "near" the function in any interesting sense. IS_PUBLIC controls whether 833*e4b17023SJohn Marino the symbol can be shared across the entire application (or DSO). */ 834*e4b17023SJohn Marino 835*e4b17023SJohn Marino rtx 836*e4b17023SJohn Marino dw2_force_const_mem (rtx x, bool is_public) 837*e4b17023SJohn Marino { 838*e4b17023SJohn Marino splay_tree_node node; 839*e4b17023SJohn Marino const char *key; 840*e4b17023SJohn Marino tree decl_id; 841*e4b17023SJohn Marino 842*e4b17023SJohn Marino if (! indirect_pool) 843*e4b17023SJohn Marino /* We use strcmp, rather than just comparing pointers, so that the 844*e4b17023SJohn Marino sort order will not depend on the host system. */ 845*e4b17023SJohn Marino indirect_pool = splay_tree_new_ggc (splay_tree_compare_strings, 846*e4b17023SJohn Marino ggc_alloc_splay_tree_str_tree_node_splay_tree_s, 847*e4b17023SJohn Marino ggc_alloc_splay_tree_str_tree_node_splay_tree_node_s); 848*e4b17023SJohn Marino 849*e4b17023SJohn Marino gcc_assert (GET_CODE (x) == SYMBOL_REF); 850*e4b17023SJohn Marino 851*e4b17023SJohn Marino key = XSTR (x, 0); 852*e4b17023SJohn Marino node = splay_tree_lookup (indirect_pool, (splay_tree_key) key); 853*e4b17023SJohn Marino if (node) 854*e4b17023SJohn Marino decl_id = (tree) node->value; 855*e4b17023SJohn Marino else 856*e4b17023SJohn Marino { 857*e4b17023SJohn Marino tree id; 858*e4b17023SJohn Marino const char *str = targetm.strip_name_encoding (key); 859*e4b17023SJohn Marino 860*e4b17023SJohn Marino if (is_public && USE_LINKONCE_INDIRECT) 861*e4b17023SJohn Marino { 862*e4b17023SJohn Marino char *ref_name = XALLOCAVEC (char, strlen (str) + sizeof "DW.ref."); 863*e4b17023SJohn Marino 864*e4b17023SJohn Marino sprintf (ref_name, "DW.ref.%s", str); 865*e4b17023SJohn Marino gcc_assert (!maybe_get_identifier (ref_name)); 866*e4b17023SJohn Marino decl_id = get_identifier (ref_name); 867*e4b17023SJohn Marino TREE_PUBLIC (decl_id) = 1; 868*e4b17023SJohn Marino } 869*e4b17023SJohn Marino else 870*e4b17023SJohn Marino { 871*e4b17023SJohn Marino char label[32]; 872*e4b17023SJohn Marino 873*e4b17023SJohn Marino ASM_GENERATE_INTERNAL_LABEL (label, "LDFCM", dw2_const_labelno); 874*e4b17023SJohn Marino ++dw2_const_labelno; 875*e4b17023SJohn Marino gcc_assert (!maybe_get_identifier (label)); 876*e4b17023SJohn Marino decl_id = get_identifier (label); 877*e4b17023SJohn Marino } 878*e4b17023SJohn Marino 879*e4b17023SJohn Marino id = maybe_get_identifier (str); 880*e4b17023SJohn Marino if (id) 881*e4b17023SJohn Marino TREE_SYMBOL_REFERENCED (id) = 1; 882*e4b17023SJohn Marino 883*e4b17023SJohn Marino splay_tree_insert (indirect_pool, (splay_tree_key) key, 884*e4b17023SJohn Marino (splay_tree_value) decl_id); 885*e4b17023SJohn Marino } 886*e4b17023SJohn Marino 887*e4b17023SJohn Marino return gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (decl_id)); 888*e4b17023SJohn Marino } 889*e4b17023SJohn Marino 890*e4b17023SJohn Marino /* A helper function for dw2_output_indirect_constants called through 891*e4b17023SJohn Marino splay_tree_foreach. Emit one queued constant to memory. */ 892*e4b17023SJohn Marino 893*e4b17023SJohn Marino static int 894*e4b17023SJohn Marino dw2_output_indirect_constant_1 (splay_tree_node node, 895*e4b17023SJohn Marino void *data ATTRIBUTE_UNUSED) 896*e4b17023SJohn Marino { 897*e4b17023SJohn Marino const char *sym; 898*e4b17023SJohn Marino rtx sym_ref; 899*e4b17023SJohn Marino tree id, decl; 900*e4b17023SJohn Marino 901*e4b17023SJohn Marino sym = (const char *) node->key; 902*e4b17023SJohn Marino id = (tree) node->value; 903*e4b17023SJohn Marino 904*e4b17023SJohn Marino decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, id, ptr_type_node); 905*e4b17023SJohn Marino SET_DECL_ASSEMBLER_NAME (decl, id); 906*e4b17023SJohn Marino DECL_ARTIFICIAL (decl) = 1; 907*e4b17023SJohn Marino DECL_IGNORED_P (decl) = 1; 908*e4b17023SJohn Marino DECL_INITIAL (decl) = decl; 909*e4b17023SJohn Marino TREE_READONLY (decl) = 1; 910*e4b17023SJohn Marino 911*e4b17023SJohn Marino if (TREE_PUBLIC (id)) 912*e4b17023SJohn Marino { 913*e4b17023SJohn Marino TREE_PUBLIC (decl) = 1; 914*e4b17023SJohn Marino make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl)); 915*e4b17023SJohn Marino if (USE_LINKONCE_INDIRECT) 916*e4b17023SJohn Marino DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN; 917*e4b17023SJohn Marino } 918*e4b17023SJohn Marino else 919*e4b17023SJohn Marino TREE_STATIC (decl) = 1; 920*e4b17023SJohn Marino 921*e4b17023SJohn Marino sym_ref = gen_rtx_SYMBOL_REF (Pmode, sym); 922*e4b17023SJohn Marino assemble_variable (decl, 1, 1, 1); 923*e4b17023SJohn Marino assemble_integer (sym_ref, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1); 924*e4b17023SJohn Marino 925*e4b17023SJohn Marino return 0; 926*e4b17023SJohn Marino } 927*e4b17023SJohn Marino 928*e4b17023SJohn Marino /* Emit the constants queued through dw2_force_const_mem. */ 929*e4b17023SJohn Marino 930*e4b17023SJohn Marino void 931*e4b17023SJohn Marino dw2_output_indirect_constants (void) 932*e4b17023SJohn Marino { 933*e4b17023SJohn Marino if (indirect_pool) 934*e4b17023SJohn Marino splay_tree_foreach (indirect_pool, dw2_output_indirect_constant_1, NULL); 935*e4b17023SJohn Marino } 936*e4b17023SJohn Marino 937*e4b17023SJohn Marino /* Like dw2_asm_output_addr_rtx, but encode the pointer as directed. 938*e4b17023SJohn Marino If PUBLIC is set and the encoding is DW_EH_PE_indirect, the indirect 939*e4b17023SJohn Marino reference is shared across the entire application (or DSO). */ 940*e4b17023SJohn Marino 941*e4b17023SJohn Marino void 942*e4b17023SJohn Marino dw2_asm_output_encoded_addr_rtx (int encoding, rtx addr, bool is_public, 943*e4b17023SJohn Marino const char *comment, ...) 944*e4b17023SJohn Marino { 945*e4b17023SJohn Marino int size; 946*e4b17023SJohn Marino va_list ap; 947*e4b17023SJohn Marino 948*e4b17023SJohn Marino va_start (ap, comment); 949*e4b17023SJohn Marino 950*e4b17023SJohn Marino size = size_of_encoded_value (encoding); 951*e4b17023SJohn Marino 952*e4b17023SJohn Marino if (encoding == DW_EH_PE_aligned) 953*e4b17023SJohn Marino { 954*e4b17023SJohn Marino assemble_align (POINTER_SIZE); 955*e4b17023SJohn Marino assemble_integer (addr, size, POINTER_SIZE, 1); 956*e4b17023SJohn Marino va_end (ap); 957*e4b17023SJohn Marino return; 958*e4b17023SJohn Marino } 959*e4b17023SJohn Marino 960*e4b17023SJohn Marino /* NULL is _always_ represented as a plain zero, as is 1 for Ada's 961*e4b17023SJohn Marino "all others". */ 962*e4b17023SJohn Marino if (addr == const0_rtx || addr == const1_rtx) 963*e4b17023SJohn Marino assemble_integer (addr, size, BITS_PER_UNIT, 1); 964*e4b17023SJohn Marino else 965*e4b17023SJohn Marino { 966*e4b17023SJohn Marino restart: 967*e4b17023SJohn Marino /* Allow the target first crack at emitting this. Some of the 968*e4b17023SJohn Marino special relocations require special directives instead of 969*e4b17023SJohn Marino just ".4byte" or whatever. */ 970*e4b17023SJohn Marino #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX 971*e4b17023SJohn Marino ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX (asm_out_file, encoding, size, 972*e4b17023SJohn Marino addr, done); 973*e4b17023SJohn Marino #endif 974*e4b17023SJohn Marino 975*e4b17023SJohn Marino /* Indirection is used to get dynamic relocations out of a 976*e4b17023SJohn Marino read-only section. */ 977*e4b17023SJohn Marino if (encoding & DW_EH_PE_indirect) 978*e4b17023SJohn Marino { 979*e4b17023SJohn Marino /* It is very tempting to use force_const_mem so that we share data 980*e4b17023SJohn Marino with the normal constant pool. However, we've already emitted 981*e4b17023SJohn Marino the constant pool for this function. Moreover, we'd like to 982*e4b17023SJohn Marino share these constants across the entire unit of translation and 983*e4b17023SJohn Marino even, if possible, across the entire application (or DSO). */ 984*e4b17023SJohn Marino addr = dw2_force_const_mem (addr, is_public); 985*e4b17023SJohn Marino encoding &= ~DW_EH_PE_indirect; 986*e4b17023SJohn Marino goto restart; 987*e4b17023SJohn Marino } 988*e4b17023SJohn Marino 989*e4b17023SJohn Marino switch (encoding & 0xF0) 990*e4b17023SJohn Marino { 991*e4b17023SJohn Marino case DW_EH_PE_absptr: 992*e4b17023SJohn Marino dw2_assemble_integer (size, addr); 993*e4b17023SJohn Marino break; 994*e4b17023SJohn Marino 995*e4b17023SJohn Marino case DW_EH_PE_pcrel: 996*e4b17023SJohn Marino gcc_assert (GET_CODE (addr) == SYMBOL_REF); 997*e4b17023SJohn Marino #ifdef ASM_OUTPUT_DWARF_PCREL 998*e4b17023SJohn Marino ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, XSTR (addr, 0)); 999*e4b17023SJohn Marino #else 1000*e4b17023SJohn Marino dw2_assemble_integer (size, gen_rtx_MINUS (Pmode, addr, pc_rtx)); 1001*e4b17023SJohn Marino #endif 1002*e4b17023SJohn Marino break; 1003*e4b17023SJohn Marino 1004*e4b17023SJohn Marino default: 1005*e4b17023SJohn Marino /* Other encodings should have been handled by 1006*e4b17023SJohn Marino ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX. */ 1007*e4b17023SJohn Marino gcc_unreachable (); 1008*e4b17023SJohn Marino } 1009*e4b17023SJohn Marino 1010*e4b17023SJohn Marino #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX 1011*e4b17023SJohn Marino done:; 1012*e4b17023SJohn Marino #endif 1013*e4b17023SJohn Marino } 1014*e4b17023SJohn Marino 1015*e4b17023SJohn Marino if (flag_debug_asm && comment) 1016*e4b17023SJohn Marino { 1017*e4b17023SJohn Marino fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START); 1018*e4b17023SJohn Marino vfprintf (asm_out_file, comment, ap); 1019*e4b17023SJohn Marino } 1020*e4b17023SJohn Marino fputc ('\n', asm_out_file); 1021*e4b17023SJohn Marino 1022*e4b17023SJohn Marino va_end (ap); 1023*e4b17023SJohn Marino } 1024*e4b17023SJohn Marino 1025*e4b17023SJohn Marino #include "gt-dwarf2asm.h" 1026