diff options
author | YamaArashi <shadow962@live.com> | 2016-07-24 11:39:52 -0700 |
---|---|---|
committer | YamaArashi <shadow962@live.com> | 2016-07-24 11:39:52 -0700 |
commit | 71785b8fc6c42b1f0fc482f38f6a3e32f878efef (patch) | |
tree | 3857b92a890fa823e4d253b3f58ff1596c0cd102 | |
parent | d3de54b9e1cf35ce1cf248d30fa6b6a90f7849fd (diff) |
add -fhex-asm option
-rwxr-xr-x | gcc/final.c | 99 | ||||
-rwxr-xr-x | gcc/flags.h | 5 | ||||
-rwxr-xr-x | gcc/thumb.c | 26 | ||||
-rwxr-xr-x | gcc/thumb.h | 24 | ||||
-rwxr-xr-x | gcc/toplev.c | 7 |
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])) |