mirror of
https://github.com/pret/agbcc.git
synced 2026-08-25 20:04:06 -05:00
add -fhex-asm option
This commit is contained in:
99
gcc/final.c
99
gcc/final.c
@@ -338,6 +338,12 @@ static rtx *uid_align;
|
||||
static int *uid_shuid;
|
||||
static struct label_alignment *label_align;
|
||||
|
||||
static void
|
||||
print_wint(FILE *file, HOST_WIDE_INT value)
|
||||
{
|
||||
fprintf(file, flag_hex_asm ? HOST_WIDE_INT_PRINT_HEX : HOST_WIDE_INT_PRINT_DEC, value);
|
||||
}
|
||||
|
||||
/* Indicate that branch shortening hasn't yet been done. */
|
||||
|
||||
void
|
||||
@@ -439,34 +445,34 @@ get_attr_length (insn)
|
||||
|
||||
Call a sequence of instructions beginning with alignment point X
|
||||
and continuing until the next alignment point `block X'. When `X'
|
||||
is used in an expression, it means the alignment value of the
|
||||
is used in an expression, it means the alignment value of the
|
||||
alignment point.
|
||||
|
||||
|
||||
Call the distance between the start of the first insn of block X, and
|
||||
the end of the last insn of block X `IX', for the `inner size of X'.
|
||||
This is clearly the sum of the instruction lengths.
|
||||
|
||||
|
||||
Likewise with the next alignment-delimited block following X, which we
|
||||
shall call block Y.
|
||||
|
||||
|
||||
Call the distance between the start of the first insn of block X, and
|
||||
the start of the first insn of block Y `OX', for the `outer size of X'.
|
||||
|
||||
|
||||
The estimated padding is then OX - IX.
|
||||
|
||||
|
||||
OX can be safely estimated as
|
||||
|
||||
|
||||
if (X >= Y)
|
||||
OX = round_up(IX, Y)
|
||||
else
|
||||
OX = round_up(IX, X) + Y - X
|
||||
|
||||
|
||||
Clearly est(IX) >= real(IX), because that only depends on the
|
||||
instruction lengths, and those being overestimated is a given.
|
||||
|
||||
|
||||
Clearly round_up(foo, Z) >= round_up(bar, Z) if foo >= bar, so
|
||||
we needn't worry about that when thinking about OX.
|
||||
|
||||
|
||||
When X >= Y, the alignment provided by Y adds no uncertainty factor
|
||||
for branch ranges starting before X, so we can just round what we have.
|
||||
But when X < Y, we don't know anything about the, so to speak,
|
||||
@@ -712,7 +718,7 @@ shorten_branches (first)
|
||||
/* We use max_log here to keep track of the maximum alignment we want to
|
||||
impose on the next CODE_LABEL (or the current one if we are processing
|
||||
the CODE_LABEL itself). */
|
||||
|
||||
|
||||
max_log = 0;
|
||||
max_skip = 0;
|
||||
|
||||
@@ -883,7 +889,7 @@ shorten_branches (first)
|
||||
}
|
||||
|
||||
insn_addresses[uid] = insn_current_address;
|
||||
|
||||
|
||||
if (GET_CODE (insn) == NOTE || GET_CODE (insn) == BARRIER
|
||||
|| GET_CODE (insn) == CODE_LABEL)
|
||||
continue;
|
||||
@@ -924,7 +930,7 @@ shorten_branches (first)
|
||||
* insn_default_length (inner_insn));
|
||||
else
|
||||
inner_length = insn_default_length (inner_insn);
|
||||
|
||||
|
||||
insn_lengths[inner_uid] = inner_length;
|
||||
varying_length[inner_uid] = 0;
|
||||
insn_lengths[uid] += inner_length;
|
||||
@@ -989,7 +995,7 @@ shorten_branches (first)
|
||||
if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
body = PATTERN (insn);
|
||||
new_length = 0;
|
||||
for (i = 0; i < XVECLEN (body, 0); i++)
|
||||
@@ -1200,7 +1206,7 @@ final (first, file, optimize, prescan)
|
||||
}
|
||||
|
||||
/* Initialize insn_eh_region table if eh is being used. */
|
||||
|
||||
|
||||
init_insn_eh_region (first, max_uid);
|
||||
|
||||
init_recog ();
|
||||
@@ -1858,7 +1864,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
|
||||
&& set != 0)
|
||||
{
|
||||
rtx cond_rtx, then_rtx, else_rtx;
|
||||
|
||||
|
||||
if (GET_CODE (insn) != JUMP_INSN
|
||||
&& GET_CODE (SET_SRC (set)) == IF_THEN_ELSE)
|
||||
{
|
||||
@@ -1872,7 +1878,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
|
||||
then_rtx = const_true_rtx;
|
||||
else_rtx = const0_rtx;
|
||||
}
|
||||
|
||||
|
||||
switch (GET_CODE (cond_rtx))
|
||||
{
|
||||
case GTU:
|
||||
@@ -2006,7 +2012,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
|
||||
/* If we didn't split the insn, go away. */
|
||||
if (new == insn && PATTERN (new) == body)
|
||||
fatal_insn ("Could not split insn", insn);
|
||||
|
||||
|
||||
#ifdef HAVE_ATTR_length
|
||||
/* This instruction should have been split in shorten_branches,
|
||||
to ensure that we would have valid length info for the
|
||||
@@ -2016,7 +2022,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
|
||||
if (prescan > 0)
|
||||
break;
|
||||
|
||||
@@ -2166,7 +2172,7 @@ walk_alter_subreg (x)
|
||||
|
||||
case SUBREG:
|
||||
return alter_subreg (x);
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -2227,7 +2233,7 @@ alter_cond (cond)
|
||||
PUT_CODE (cond, NE);
|
||||
value = 2;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -2256,7 +2262,7 @@ alter_cond (cond)
|
||||
PUT_CODE (cond, NE);
|
||||
value = 2;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -2281,7 +2287,7 @@ alter_cond (cond)
|
||||
case LTU:
|
||||
/* Jump becomes no-op. */
|
||||
return -1;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -2377,7 +2383,7 @@ output_asm_name ()
|
||||
if (debug_insn)
|
||||
{
|
||||
register int num = INSN_CODE (debug_insn);
|
||||
fprintf (asm_out_file, "\t%s %d\t%s",
|
||||
fprintf (asm_out_file, "\t%s %d\t%s",
|
||||
ASM_COMMENT_START, INSN_UID (debug_insn), insn_name[num]);
|
||||
if (insn_n_alternatives[num] > 1)
|
||||
fprintf (asm_out_file, "/%d", which_alternative + 1);
|
||||
@@ -2472,8 +2478,9 @@ output_asm_insn (template, operands)
|
||||
else if (letter == 'n')
|
||||
{
|
||||
if (GET_CODE (operands[c]) == CONST_INT)
|
||||
fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC,
|
||||
- INTVAL (operands[c]));
|
||||
{
|
||||
print_wint(asm_out_file, -INTVAL(operands[c]));
|
||||
}
|
||||
else
|
||||
{
|
||||
putc ('-', asm_out_file);
|
||||
@@ -2482,7 +2489,7 @@ output_asm_insn (template, operands)
|
||||
}
|
||||
else
|
||||
output_operand (operands[c], letter);
|
||||
|
||||
|
||||
while ((c = *p) >= '0' && c <= '9') p++;
|
||||
}
|
||||
/* % followed by a digit outputs an operand the default way. */
|
||||
@@ -2561,15 +2568,41 @@ output_operand (x, code)
|
||||
}
|
||||
|
||||
/* Print a memory reference operand for address X
|
||||
using machine-dependent assembler syntax.
|
||||
The macro PRINT_OPERAND_ADDRESS exists just to control this function. */
|
||||
using machine-dependent assembler syntax. */
|
||||
|
||||
void
|
||||
output_address (x)
|
||||
rtx x;
|
||||
{
|
||||
walk_alter_subreg (x);
|
||||
PRINT_OPERAND_ADDRESS (asm_out_file, x);
|
||||
walk_alter_subreg (x);
|
||||
|
||||
if (GET_CODE(x) == REG)
|
||||
{
|
||||
fprintf(asm_out_file, "[%s]", reg_names[REGNO(x)]);
|
||||
}
|
||||
else if (GET_CODE(x) == POST_INC)
|
||||
{
|
||||
fprintf(asm_out_file, "%s!", reg_names[REGNO(XEXP(x, 0))]);
|
||||
}
|
||||
else if (GET_CODE(x) == PLUS)
|
||||
{
|
||||
if (GET_CODE(XEXP(x, 1)) == CONST_INT)
|
||||
{
|
||||
fprintf(asm_out_file, "[%s, #", reg_names[REGNO(XEXP(x, 0))]);
|
||||
print_wint(asm_out_file, INTVAL(XEXP(x, 1)));
|
||||
fprintf(asm_out_file, "]");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(asm_out_file, "[%s, %s]",
|
||||
reg_names[REGNO(XEXP(x, 0))],
|
||||
reg_names[REGNO(XEXP(x, 1))]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
output_addr_const(asm_out_file, x);
|
||||
}
|
||||
}
|
||||
|
||||
/* Print an integer constant expression in assembler syntax.
|
||||
@@ -2605,7 +2638,7 @@ output_addr_const (file, x)
|
||||
break;
|
||||
|
||||
case CONST_INT:
|
||||
fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
|
||||
print_wint(file, INTVAL(x));
|
||||
break;
|
||||
|
||||
case CONST:
|
||||
@@ -2624,7 +2657,7 @@ output_addr_const (file, x)
|
||||
else if (CONST_DOUBLE_LOW (x) < 0)
|
||||
fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (x));
|
||||
else
|
||||
fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
|
||||
print_wint(file, CONST_DOUBLE_LOW(x));
|
||||
}
|
||||
else
|
||||
/* We can't handle floating point constants;
|
||||
|
||||
@@ -394,7 +394,7 @@ extern int flag_regmove;
|
||||
|
||||
/* Instrument functions with calls at entry and exit, for profiling. */
|
||||
extern int flag_instrument_function_entry_exit;
|
||||
|
||||
|
||||
/* Other basic status info about current function. */
|
||||
|
||||
/* Nonzero means current function must be given a frame pointer.
|
||||
@@ -447,3 +447,6 @@ enum graph_dump_types
|
||||
vcg
|
||||
};
|
||||
extern enum graph_dump_types graph_dump_format;
|
||||
|
||||
/* Nonzero if ASM output should use hex instead of decimal. */
|
||||
extern int flag_hex_asm;
|
||||
|
||||
26
gcc/thumb.c
26
gcc/thumb.c
@@ -767,8 +767,12 @@ thumb_function_prologue(FILE *f, int frame_size)
|
||||
asm_fprintf(f, "}\n");
|
||||
}
|
||||
else
|
||||
asm_fprintf(f, "\tsub\t%Rsp, %Rsp, #%d\n",
|
||||
current_function_pretend_args_size);
|
||||
{
|
||||
if (flag_hex_asm)
|
||||
asm_fprintf(f, "\tsub\t%Rsp, %Rsp, #0x%x\n", current_function_pretend_args_size);
|
||||
else
|
||||
asm_fprintf(f, "\tsub\t%Rsp, %Rsp, #%d\n", current_function_pretend_args_size);
|
||||
}
|
||||
}
|
||||
|
||||
for (regno = 0; regno < 8; regno++)
|
||||
@@ -1090,10 +1094,20 @@ thumb_unexpanded_epilogue()
|
||||
}
|
||||
|
||||
/* Remove the argument registers that were pushed onto the stack. */
|
||||
asm_fprintf(asm_out_file, "\tadd\t%s, %s, #%d\n",
|
||||
reg_names[STACK_POINTER],
|
||||
reg_names[STACK_POINTER],
|
||||
current_function_pretend_args_size);
|
||||
if (flag_hex_asm)
|
||||
{
|
||||
asm_fprintf(asm_out_file, "\tadd\t%s, %s, #0x%x\n",
|
||||
reg_names[STACK_POINTER],
|
||||
reg_names[STACK_POINTER],
|
||||
current_function_pretend_args_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
asm_fprintf(asm_out_file, "\tadd\t%s, %s, #%d\n",
|
||||
reg_names[STACK_POINTER],
|
||||
reg_names[STACK_POINTER],
|
||||
current_function_pretend_args_size);
|
||||
}
|
||||
|
||||
thumb_exit(asm_out_file, had_to_push_lr ? ARG_4_REGISTER : LINK_REGISTER);
|
||||
}
|
||||
|
||||
24
gcc/thumb.h
24
gcc/thumb.h
@@ -1013,33 +1013,9 @@ int thumb_shiftable_const ();
|
||||
&& GET_CODE (XEXP (X, 1)) == CONST_INT)) \
|
||||
? 1 : 2)
|
||||
|
||||
|
||||
/* Position Independent Code */
|
||||
|
||||
#define PRINT_OPERAND(STREAM,X,CODE) \
|
||||
thumb_print_operand((STREAM), (X), (CODE))
|
||||
|
||||
#define PRINT_OPERAND_ADDRESS(STREAM,X) \
|
||||
{ \
|
||||
if (GET_CODE ((X)) == REG) \
|
||||
fprintf ((STREAM), "[%s]", reg_names[REGNO ((X))]); \
|
||||
else if (GET_CODE ((X)) == POST_INC) \
|
||||
fprintf ((STREAM), "%s!", reg_names[REGNO (XEXP (X, 0))]); \
|
||||
else if (GET_CODE ((X)) == PLUS) \
|
||||
{ \
|
||||
if (GET_CODE (XEXP ((X), 1)) == CONST_INT) \
|
||||
fprintf ((STREAM), "[%s, #%d]", \
|
||||
reg_names[REGNO (XEXP ((X), 0))], \
|
||||
(int) INTVAL (XEXP ((X), 1))); \
|
||||
else \
|
||||
fprintf ((STREAM), "[%s, %s]", \
|
||||
reg_names[REGNO (XEXP ((X), 0))], \
|
||||
reg_names[REGNO (XEXP ((X), 1))]); \
|
||||
} \
|
||||
else \
|
||||
output_addr_const ((STREAM), (X)); \
|
||||
}
|
||||
|
||||
#define PRINT_OPERAND_PUNCT_VALID_P(CODE) ((CODE) == '@' || ((CODE) == '_'))
|
||||
|
||||
#define ASM_OUTPUT_REG_PUSH(STREAM,REGNO) \
|
||||
|
||||
@@ -581,6 +581,9 @@ int flag_strict_aliasing = 0;
|
||||
/* Instrument functions with calls at entry and exit, for profiling. */
|
||||
int flag_instrument_function_entry_exit = 0;
|
||||
|
||||
/* Use hex instead of decimal in ASM output. */
|
||||
int flag_hex_asm = 0;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *string;
|
||||
@@ -717,7 +720,9 @@ lang_independent_options f_options[] =
|
||||
{"dump-unnumbered", &flag_dump_unnumbered, 1,
|
||||
"Suppress output of instruction numbers and line number notes in debugging dumps"},
|
||||
{"instrument-functions", &flag_instrument_function_entry_exit, 1,
|
||||
"Instrument function entry/exit with profiling calls"}
|
||||
"Instrument function entry/exit with profiling calls"},
|
||||
{"hex-asm", &flag_hex_asm, 1,
|
||||
"Use hex instead of decimal in assembly output"},
|
||||
};
|
||||
|
||||
#define NUM_ELEM(a) (sizeof (a) / sizeof ((a)[0]))
|
||||
|
||||
Reference in New Issue
Block a user