summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYamaArashi <shadow962@live.com>2016-07-24 11:39:52 -0700
committerYamaArashi <shadow962@live.com>2016-07-24 11:39:52 -0700
commit71785b8fc6c42b1f0fc482f38f6a3e32f878efef (patch)
tree3857b92a890fa823e4d253b3f58ff1596c0cd102
parentd3de54b9e1cf35ce1cf248d30fa6b6a90f7849fd (diff)
add -fhex-asm option
-rwxr-xr-xgcc/final.c99
-rwxr-xr-xgcc/flags.h5
-rwxr-xr-xgcc/thumb.c26
-rwxr-xr-xgcc/thumb.h24
-rwxr-xr-xgcc/toplev.c7
5 files changed, 96 insertions, 65 deletions
diff --git a/gcc/final.c b/gcc/final.c
index e8d3337..a886f87 100755
--- a/gcc/final.c
+++ b/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;
diff --git a/gcc/flags.h b/gcc/flags.h
index 737efb5..754096f 100755
--- a/gcc/flags.h
+++ b/gcc/flags.h
@@ -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;
diff --git a/gcc/thumb.c b/gcc/thumb.c
index 954812c..ac122f7 100755
--- a/gcc/thumb.c
+++ b/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);
}
diff --git a/gcc/thumb.h b/gcc/thumb.h
index 88eee88..a271ed7 100755
--- a/gcc/thumb.h
+++ b/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) \
diff --git a/gcc/toplev.c b/gcc/toplev.c
index a39ae12..241900d 100755
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -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]))