This is the mail archive of the crossgcc@cygnus.com mailing list for the crossgcc project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Dave Madsen wrote: > It is not a Super 8 but a SuperH1 (SH1) SH7034 and it does not have > a branch far (braf) instruction. That was added in the SH2 > instruction set. > It > worked great, except a certain path through the code has a very large > loop ~600 lines (I did not write it) . When the end of the loop is > reached the compiler has generated a braf instruction which is not > valid on this processor and the processor goes off into the weeds > when trying to execute it. All of the other opcodes are fine so I > know that I am set up for the right micro. Ok, I looked in the source for egcs-1.1 and in the directory egcs-1.1b/gcc/config/sh in lib1funcs.asm there are code fragments reading: 194 #ifdef __sh1__ 195 add r5,r0 196 jmp @r0 197 #else 198 braf r5 199 #endif so it's checking for the sh1. but in sh.c there's the following: 543 char * 544 output_far_jump (insn, op) 545 rtx insn; 546 rtx op; 547 { 548 struct { rtx lab, reg, op; } this; 549 char *jump; 550 int far; 551 int offset = branch_dest (insn) - insn_addresses[INSN_UID (insn)]; 552 553 this.lab = gen_label_rtx (); 554 555 if (offset >= -32764 && offset - get_attr_length (insn) <= 32766) 556 { 557 far = 0; 558 jump = "mov.w %O0,%1;braf %1"; 559 } 560 else 561 { 562 far = 1; 563 jump = "mov.l %O0,%1;jmp @%1"; 564 } where the function output_far_jump will emit a braf instruction and it isn't checking for sh1's. You can see the output_far_jump call used in sh.md here: (which applies to sh1,sh2,sh3 and sh3e targets) 2377 ;; ------------------------------------------------------------------------ 2378 ;; Jump and linkage insns 2379 ;; ------------------------------------------------------------------------ 2380 2381 (define_insn "jump" 2382 [(set (pc) 2383 (label_ref (match_operand 0 "" "")))] 2384 "" 2385 "* 2386 { 2387 /* The length is 16 if the delay slot is unfilled. */ 2388 if (get_attr_length(insn) > 4) 2389 return output_far_jump(insn, operands[0]); 2390 else 2391 return \"bra %l0%#\"; 2392 }" 2393 [(set_attr "type" "jump") 2394 (set_attr "needs_delay_slot" "yes")]) Yup, looks like there may be a problem with egcs for SH1 possibly generating a braf under certain conditions. The bad news is I don't know how to fix it myself. Probably ouput_far jump needs to do something like the code in lib1funcs.asm but I don't know which registers are valid at that point. I believe the maintainer for this part of egcs is Jeffrey A Law law@cygnus.com, he might know for sure if it's really a compiler bug and what to do about it. You might want to try submitting this as a bug report. In the mean time, you might try breaking up the code within the "big loop" and that should work around causing the braf call for now. cheers randall -- |\/| |/\| randall@elgar.com |\/| rsl@zanshinsys.com http://www.zanshinsys.com _______________________________________________ New CrossGCC FAQ: http://www.objsw.com/CrossGCC _______________________________________________ To remove yourself from the crossgcc list, send mail to crossgcc-request@cygnus.com with the text 'unsubscribe' (without the quotes) in the body of the message.