Re: handling of long conditional branches

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Thanks Ian.

Hi,

As discussed, based on the length of the instruction I have converted the
short branch into long branch as follows: 

(define_insn "*branch"
  [(set (pc)
	(if_then_else (match_operator 1 "compare_op" [(match_operand:SI 0
"register_operand" "r") (match_operand:SI 2 "register_operand" "r")])
		(label_ref (match_operand 3 "" ""))
		(pc)))]
  ""
  "*
{
	if(get_attr_length (insn) == 6)
	{
		return output_longbranch (insn, operands);
	}
	else
	{	
		return output_branch (insn, operands);
	}
}"
  [(set_attr "type" "branch")
   (set (attr "length") (if_then_else (lt (match_dup 3) (const_int 4096))
                                           (const_int 4)
                                           (const_int 6)))])

The build is successful with the above change.

Now I have to disable the filling of delay slots in-case of long branches.
I decided to handle this using an attribute "needs_delay_slot". Hence I
added the code to set the attribute "needs_delay_slot" in the above
mentioned machine description as follows:


(define_insn "*branch"
  [(set (pc)
	(if_then_else (match_operator 1 "compare_op" [(match_operand:SI 0
"register_operand" "r") (match_operand:SI 2 "register_operand" "r")])
		(label_ref (match_operand 3 "" ""))
		(pc)))]
  ""
  "*
{
	if(get_attr_length (insn) == 6)
	{
		return output_longbranch (insn, operands);
	}
	else
	{	
		return output_branch (insn, operands);
	}
}"
  [(set_attr "type" "branch")
   (set (attr "length") (if_then_else (lt (match_dup 3) (const_int 4096))
                                           (const_int 4)
                                           (const_int 6)))
   (set (attr "needs_delay_slot") (if_then_else (lt (match_dup 3)
(const_int 4096))
                                           (const_string "yes")
                                           (const_string "no")))])


On building the GCC, I get the following error:

-- cut --
_muldi3
xgcc: Internal compiler error: program cc1 got fatal signal 11
-- cut --

I couldn't figure out what went wrong on adding this.

Could someone help me on this?

Thank you,
Chandra Kumar.


On Fri, 18 Jun 2010 08:51:39 -0700, Ian Lance Taylor <iant@xxxxxxxxxx>
wrote:
> <chandrakumar@xxxxxxxxxxxxxxx> writes:
> 
>> I am working with gcc-2.95.3 ported to a RISC architecture. 
> 
> gcc 2.95.3 is really old.
> 
> 
>> I did a modification in the port to insert 'nop' instruction. This is
>> done
>> to fix a defect. When I built the compiler (with this fix) and used it
to
>> build the glibc I got the assembler error "Relocation overflow".
>>
>> On analysis it is found that the RISC architecture has conditional
>> branches that can address destinations with a depth of 4000 bytes. This
>> limitation is not considered while doing the port.
>>
>> After the fix I did, some conditional branches addressed destination
that
>> were beyond the 4000 bytes breaking the limitation.
>>
>> Now I want to fix this case as follows:
>> 1. Conditionally branch to the maximum depth it (a conditional branch)
>> can
>> address (i.e. branch to a temporary place within the allowed range)
>> 2. Then jump from there to the actual destination.
> 
> Most gcc ports address this by counting instruction sizes and choosing
> either a long or a short branch depending on how far the branch has to
> go.  E.g., the MIPS port does this.  For MIPS the long branch is a
> short conditional branch around a long unconditional branch.  In
> mips.md see mips_output_conditional_branch and the value of the
> "length" attribute for an instruction with type "branch".
> 
> If you are inserting nops in the compiler, then you should be able to
> calculate lenghts correctly.  However, I have no idea if the framework
> for this was present in gcc 2.95.3.
> 
> Ian


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux