return true;
}
+#ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
+/* Implement TARGET_MANGLE_FUNDAMENTAL_TYPE. */
+
+static const char *
+alpha_mangle_fundamental_type (tree type)
+{
+ if (TYPE_MAIN_VARIANT (type) == long_double_type_node
+ && TARGET_LONG_DOUBLE_128)
+ return "g";
+
+ /* For all other types, use normal C++ mangling. */
+ return NULL;
+}
+#endif
+
/* Parse target option strings. */
void
REAL_MODE_FORMAT (DFmode) = &vax_g_format;
REAL_MODE_FORMAT (TFmode) = NULL;
}
+
+#ifdef TARGET_DEFAULT_LONG_DOUBLE_128
+ if (!(target_flags_explicit & MASK_LONG_DOUBLE_128))
+ target_flags |= MASK_LONG_DOUBLE_128;
+#endif
}
\f
/* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
operands[1]));
}
-/* Split a TFmode OP[1] into DImode OP[2,3] and likewise for
- OP[0] into OP[0,1]. Naturally, output operand ordering is
- little-endian. */
-
+/* Split a TImode or TFmode move from OP[1] to OP[0] into a pair of
+ DImode moves from OP[2,3] to OP[0,1]. If FIXUP_OVERLAP is true,
+ guarantee that the sequence
+ set (OP[0] OP[2])
+ set (OP[1] OP[3])
+ is valid. Naturally, output operand ordering is little-endian.
+ This is used by *movtf_internal and *movti_internal. */
+
void
-alpha_split_tfmode_pair (rtx operands[4])
+alpha_split_tmode_pair (rtx operands[4], enum machine_mode mode,
+ bool fixup_overlap)
{
switch (GET_CODE (operands[1]))
{
operands[2] = adjust_address (operands[1], DImode, 0);
break;
+ case CONST_INT:
case CONST_DOUBLE:
- gcc_assert (operands[1] == CONST0_RTX (TFmode));
+ gcc_assert (operands[1] == CONST0_RTX (mode));
operands[2] = operands[3] = const0_rtx;
break;
default:
gcc_unreachable ();
}
+
+ if (fixup_overlap && reg_overlap_mentioned_p (operands[0], operands[3]))
+ {
+ rtx tmp;
+ tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
+ tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
+ }
}
/* Implement negtf2 or abstf2. Op0 is destination, op1 is source,
rtx scratch;
int move;
- alpha_split_tfmode_pair (operands);
+ alpha_split_tmode_pair (operands, TFmode, false);
/* Detect three flavors of operand overlap. */
move = 1;
#if TARGET_ABI_OPEN_VMS
/* Ifdef'ed cause link_section are only available then. */
- readonly_data_section ();
+ switch_to_section (readonly_data_section);
fprintf (file, "\t.align 3\n");
assemble_name (file, fnname); fputs ("..na:\n", file);
fputs ("\t.ascii \"", file);
assemble_name (file, fnname);
fputs ("\\0\"\n", file);
alpha_need_linkage (fnname, 1);
- text_section ();
+ switch_to_section (text_section);
#endif
}
#ifdef OBJECT_FORMAT_ELF
-/* Switch to the section to which we should output X. The only thing
- special we do here is to honor small data. */
+/* Return a section for X. The only special thing we do here is to
+ honor small data. */
-static void
+static section *
alpha_elf_select_rtx_section (enum machine_mode mode, rtx x,
unsigned HOST_WIDE_INT align)
{
if (TARGET_SMALL_DATA && GET_MODE_SIZE (mode) <= g_switch_value)
/* ??? Consider using mergeable sdata sections. */
- sdata_section ();
+ return sdata_section;
else
- default_elf_select_rtx_section (mode, x, align);
+ return default_elf_select_rtx_section (mode, x, align);
}
#endif /* OBJECT_FORMAT_ELF */
splay_tree_node node;
struct alpha_funcs *func;
- link_section ();
+ fprintf (stream, "\t.link\n");
fprintf (stream, "\t.align 3\n");
+ in_section = NULL;
+
node = splay_tree_lookup (alpha_funcs_tree, (splay_tree_key) fundecl);
func = (struct alpha_funcs *) node->value;
static void
vms_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
- ctors_section ();
+ switch_to_section (ctors_section);
assemble_align (BITS_PER_WORD);
assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
}
static void
vms_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
- dtors_section ();
+ switch_to_section (dtors_section);
assemble_align (BITS_PER_WORD);
assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
}
tree name_tree;
printf ("T3E__: common %s\n", name);
- common_section ();
+ in_section = NULL;
fputs("\t.endp\n\n\t.psect ", file);
assemble_name(file, name);
fprintf(file, ",%d,common\n", floor_log2 (align / BITS_PER_UNIT));
#define SECTION_MAIN (SECTION_PUBLIC << 1)
static int current_section_align;
+/* A get_unnamed_section callback for switching to the text section. */
+
+static void
+unicosmk_output_text_section_asm_op (const void *data ATTRIBUTE_UNUSED)
+{
+ static int count = 0;
+ fprintf (asm_out_file, "\t.endp\n\n\t.psect\tgcc@text___%d,code\n", count++);
+}
+
+/* A get_unnamed_section callback for switching to the data section. */
+
+static void
+unicosmk_output_data_section_asm_op (const void *data ATTRIBUTE_UNUSED)
+{
+ static int count = 1;
+ fprintf (asm_out_file, "\t.endp\n\n\t.psect\tgcc@data___%d,data\n", count++);
+}
+
+/* Implement TARGET_ASM_INIT_SECTIONS.
+
+ The Cray assembler is really weird with respect to sections. It has only
+ named sections and you can't reopen a section once it has been closed.
+ This means that we have to generate unique names whenever we want to
+ reenter the text or the data section. */
+
+static void
+unicosmk_init_sections (void)
+{
+ text_section = get_unnamed_section (SECTION_CODE,
+ unicosmk_output_text_section_asm_op,
+ NULL);
+ data_section = get_unnamed_section (SECTION_WRITE,
+ unicosmk_output_data_section_asm_op,
+ NULL);
+ readonly_data_section = data_section;
+}
+
static unsigned int
unicosmk_section_type_flags (tree decl, const char *name,
int reloc ATTRIBUTE_UNUSED)
if (machine->addr_list == NULL_RTX)
return;
- data_section ();
+ switch_to_section (data_section);
for (t = machine->addr_list; t; t = XEXP (t, 1))
unicosmk_output_addr_vec (file, XEXP (t, 0));
}
rtx ciw;
struct machine_function *machine = cfun->machine;
- ssib_section ();
+ in_section = NULL;
fprintf (file, "\t.endp\n\n\t.psect\t%s%s,data\n", user_label_prefix,
unicosmk_ssib_name ());
+ strlen (current_function_name ())/8 + 5);
}
-static char unicosmk_section_buf[100];
-
-char *
-unicosmk_text_section (void)
-{
- static int count = 0;
- sprintf (unicosmk_section_buf, "\t.endp\n\n\t.psect\tgcc@text___%d,code",
- count++);
- return unicosmk_section_buf;
-}
-
-char *
-unicosmk_data_section (void)
-{
- static int count = 1;
- sprintf (unicosmk_section_buf, "\t.endp\n\n\t.psect\tgcc@data___%d,data",
- count++);
- return unicosmk_section_buf;
-}
-
/* The Cray assembler doesn't accept extern declarations for symbols which
are defined in the same file. We have to keep track of all global
symbols which are referenced and/or defined in a source file and output
#undef TARGET_HANDLE_OPTION
#define TARGET_HANDLE_OPTION alpha_handle_option
+#ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
+#undef TARGET_MANGLE_FUNDAMENTAL_TYPE
+#define TARGET_MANGLE_FUNDAMENTAL_TYPE alpha_mangle_fundamental_type
+#endif
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f