diff options
-rw-r--r-- | cgcode.c | 2 | ||||
-rw-r--r-- | cgthumb2was.c | 45 | ||||
-rw-r--r-- | cgtypes.h | 4 |
3 files changed, 33 insertions, 18 deletions
@@ -2823,7 +2823,7 @@ void code_exit_false (char label_name[]) result_graph=s_get_a (0); label=enter_label (label_name, -# ifdef G_POWER +# if defined(G_POWER) || defined(THUMB2) FAR_CONDITIONAL_JUMP_LABEL # else 0 diff --git a/cgthumb2was.c b/cgthumb2was.c index f24a314..8171603 100644 --- a/cgthumb2was.c +++ b/cgthumb2was.c @@ -1558,11 +1558,24 @@ void w_as_jmpp_instruction (struct instruction *instruction) #endif } -static void w_as_branch_instruction (struct instruction *instruction,char *opcode) +static void w_as_branch_instruction (struct instruction *instruction,char *opcode,char *condition) { - w_as_opcode (opcode); - w_as_label_parameter (&instruction->instruction_parameters[0]); - w_as_newline_after_instruction(); + if (instruction->instruction_parameters[0].parameter_data.l->label_flags & FAR_CONDITIONAL_JUMP_LABEL) + { + w_as_opcode ("ldr"); + w_as_scratch_register_comma(); + w_as_immediate_label (instruction->instruction_parameters[0].parameter_data.l); + w_as_newline_after_instruction(); + + w_as_opcode_condition ("bx",condition,1); + w_as_scratch_register_newline(); + } + else + { + w_as_opcode_condition (opcode,condition,0); + w_as_label_parameter (&instruction->instruction_parameters[0]); + w_as_newline_after_instruction(); + } } static void as_test_floating_point_condition_code (void) @@ -2539,40 +2552,40 @@ static void w_as_instructions (struct instruction *instruction) w_as_rtsp_instruction(); break; case IBEQ: - w_as_branch_instruction (instruction,"beq"); + w_as_branch_instruction (instruction,"b","eq"); break; case IBGE: - w_as_branch_instruction (instruction,"bge"); + w_as_branch_instruction (instruction,"b","ge"); break; case IBGEU: - w_as_branch_instruction (instruction,"bhs"); + w_as_branch_instruction (instruction,"b","hs"); break; case IBGT: - w_as_branch_instruction (instruction,"bgt"); + w_as_branch_instruction (instruction,"b","gt"); break; case IBGTU: - w_as_branch_instruction (instruction,"bhi"); + w_as_branch_instruction (instruction,"b","hi"); break; case IBLE: - w_as_branch_instruction (instruction,"ble"); + w_as_branch_instruction (instruction,"b","le"); break; case IBLEU: - w_as_branch_instruction (instruction,"bls"); + w_as_branch_instruction (instruction,"b","ls"); break; case IBLT: - w_as_branch_instruction (instruction,"blt"); + w_as_branch_instruction (instruction,"b","lt"); break; case IBLTU: - w_as_branch_instruction (instruction,"blo"); + w_as_branch_instruction (instruction,"b","lo"); break; case IBNE: - w_as_branch_instruction (instruction,"bne"); + w_as_branch_instruction (instruction,"b","ne"); break; case IBO: - w_as_branch_instruction (instruction,"bvs"); + w_as_branch_instruction (instruction,"b","vs"); break; case IBNO: - w_as_branch_instruction (instruction,"bvc"); + w_as_branch_instruction (instruction,"b","vc"); break; case ILSL: w_as_shift_instruction (instruction,"lsl"); @@ -75,11 +75,13 @@ typedef struct label { #define EA_LABEL 128 #ifdef G_POWER # define HAS_TOC_LABELS 256 -# define FAR_CONDITIONAL_JUMP_LABEL 512 # define STRING_LABEL 1024 # define DOT_O_BEFORE_LABEL 2048 # define STUB_GENERATED 4096 #endif +#if defined(G_POWER) || defined(THUMB2) +# define FAR_CONDITIONAL_JUMP_LABEL 512 +#endif #if defined (G_A64) && defined (LINUX) # define USE_PLT_LABEL 4096 #endif |