From 5effb5bfcaf95ad12e42a298c2306fab36dd402e Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Sun, 2 Oct 2016 12:05:50 +0000 Subject: Fix storing the program counter The previous solution was to add 9 (8 for the offset, 1 for the Thumb state). However, the lowest bit is used for something else (garbage collection / evaluation status), so this gives some problems. This solution adds only 8 (the offset), so that we don't alter the lowest two bits. Then, when jumping, the address is IORed with 1, so that the Thumb state bit is set. --- cgthumb2was.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/cgthumb2was.c b/cgthumb2was.c index 334bd16..4881263 100644 --- a/cgthumb2was.c +++ b/cgthumb2was.c @@ -1486,7 +1486,7 @@ static void w_as_jsr_instruction (struct instruction *instruction) case P_INDIRECT_WITH_UPDATE: w_as_instruction_without_parameters (".align"); w_as_opcode ("add"); - fprintf (assembly_file,"lr,pc,#9"); + fprintf (assembly_file,"lr,pc,#8"); w_as_newline_after_instruction(); w_as_opcode ("str"); fprintf (assembly_file,"lr,[sp,#%d]!",instruction->instruction_parameters[1].parameter_offset); @@ -1500,20 +1500,18 @@ static void w_as_jsr_instruction (struct instruction *instruction) if (instruction->instruction_arity>1) w_as_instruction_without_parameters (".align"); w_as_opcode ("add"); - w_as_scratch_register_comma(); - fprintf (assembly_file,"pc,#9"); + fprintf (assembly_file,"lr,pc,#%d", + instruction->instruction_parameters[0].parameter_type==P_REGISTER ? 6 : 8); w_as_newline_after_instruction(); switch (instruction->instruction_parameters[1].parameter_type){ case P_INDIRECT_WITH_UPDATE: w_as_opcode ("str"); - w_as_scratch_register_comma(); - fprintf (assembly_file,"[sp,#%d]!",instruction->instruction_parameters[1].parameter_offset); + fprintf (assembly_file,"lr,[sp,#%d]!",instruction->instruction_parameters[1].parameter_offset); w_as_newline_after_instruction(); break; case P_INDIRECT: w_as_opcode ("str"); - w_as_scratch_register_comma(); - fprintf (assembly_file,"[sp,#%d]",instruction->instruction_parameters[1].parameter_offset); + fprintf (assembly_file,"lr,[sp,#%d]",instruction->instruction_parameters[1].parameter_offset); w_as_newline_after_instruction(); break; } @@ -2315,7 +2313,13 @@ static void w_as_fmovel_instruction (struct instruction *instruction) static void w_as_rts_instruction (void) { w_as_opcode ("ldr"); - fprintf (assembly_file,"pc,[sp],#4"); + fprintf (assembly_file,"lr,[sp],#4"); + w_as_newline_after_instruction(); + w_as_opcode ("orr"); + fprintf (assembly_file,"lr,lr,#1"); + w_as_newline_after_instruction(); + w_as_opcode ("mov"); + fprintf (assembly_file,"pc,lr"); w_as_newline_after_instruction(); write_float_constants(); -- cgit v1.2.3