LOGIN   :::   RECOVER PASS   :::   GET ACCOUNT    
Browse
  • Projects
  • Code (CVS)
  • Forums
  • News
  • Articles
  • Polls
  •  
    OpenCores
  • FAQ
  • CVS HowTo
  • Mission
  • Media
  • Tools
  • Advertise
  • Mirrors
  • Logos
  • Contact us
  • Find Resources
  • Job Opportunity
  •  
    Tools
  • Search
      
  • Download Cores (CVSGet)
  •  
    More
  • Wishbone
  • Perlilog
  • EDA tools
  • OpenTech CD
  •  
    Navigation: All forums > Openrisc > Message List > Message Post

    Message

    Reply | Reply all
    Date Prev | Date Next | Thread Prev | Thread Next Date Index | Thread Index

    From: "Damjan Lampret" <lampret@o...>
    Date: Wed, 12 Nov 2003 19:10:57 +0100
    Subject: Re: [openrisc] Optimization Problems
    Top

    Pablo,
    
    this is the floating point stuff. Properly is to use soft floating point
    library. The FPU is just being added to or1ksim and OR1200. So nobody is
    taking seriously gcc with regard to proper FP support (that's why it says
    "fake insns")
    
    regards,
    Damjan
    
    ----- Original Message ----- 
    From: <pablo.huerta@a...>
    To: <openrisc@o...>
    Sent: Wednesday, November 12, 2003 4:11 PM
    Subject: Re: [openrisc] Optimization Problems
    
    
    > Hi again:
    >
    > The bugs I have found and the way to solve them are the following:
    >
    > In File or32.md:
    >
    >      (define_insn "movdf"  [(set (match_operand:DF 0 "general_operand"
    > "=r,r,m")
    >              (match_operand:DF 1 "general_operand" "r,m,r"))]
    >        ""
    >        "*
    >        switch(which_alternative)
    >         {
    >           case 0:
    >             return \"l.addi  \\t%0,%1,0\\t # fake insn for handling DF\";
    >           case 1:
    >             return \"l.lwz    \\t%0,%1\\t # fake insn for handling DF\";
    >           case 2:
    >             return \"l.sw    \\t%0,%1\\t # fake insn for handling DF\";
    >           default:
    >             return \"invalid alternative\";
    >         }"
    >      [(set_attr "type" "move,load,store")
    >         (set_attr "length" "1,1,1")])
    >
    > Should be replaced with:
    >
    >      (define_insn "movdf"
    >              [(set (match_operand:DF 0 "nonimmediate_operand" "=r, r,
    > m, r")
    >                    (match_operand:DF 1 "general_operand"      " r, m,
    > r, i"))]
    >              ""
    >              "*
    >               return or1k_output_move_double (operands);
    >              "
    >              [(set_attr "length" "2,2,2,3")])
    >
    > And function or1k_output_move_double(operands) must be placed in
    > or1k.c. The definition for that function is as follows:
    >
    > char *
    > or1k_output_move_double(rtx *operands)
    >
    > {
    > rtx xoperands[3];
    > switch (GET_CODE (operands[0])) {
    > case REG:
    > if (GET_CODE (operands[1]) == REG)
    > {
    > if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
    > {
    > output_asm_insn ("\tl.or    \t%H0, %H1, r0", operands);
    > output_asm_insn ("\tl.or    \t%0, %1, r0", operands);
    > return "";
    > }
    > else
    > {
    > output_asm_insn ("\tl.or    \t%0, %1, r0", operands);
    > output_asm_insn ("\tl.or    \t%H0, %H1, r0", operands);
    > return "";
    > }
    > }
    > else if (GET_CODE (operands[1]) == MEM)
    > {
    > xoperands[1] = XEXP (operands[1], 0);
    > if (GET_CODE (xoperands[1]) == REG)
    > {
    > xoperands[0] = operands[0];
    > if (REGNO (xoperands[0]) == REGNO (xoperands[1]))
    > {
    > output_asm_insn ("\tl.lwz   \t%H0, 4(%1)", xoperands);
    > output_asm_insn ("\tl.lwz   \t%0, 0(%1)", xoperands);
    > return "";
    > }
    > else
    > {
    > output_asm_insn ("\tl.lwz   \t%0, 0(%1)", xoperands);
    > output_asm_insn ("\tl.lwz   \t%H0, 4(%1)", xoperands);
    > return "";
    > }
    > }
    > else if (GET_CODE (xoperands[1]) == PLUS)
    > {
    > if (GET_CODE (xoperands[2] = XEXP (xoperands[1], 1)) == REG)
    > {
    > xoperands[0] = operands[0];
    > xoperands[1] = XEXP (xoperands[1], 0);
    > if (REGNO (xoperands[0]) == REGNO (xoperands[2]))
    > {
    > output_asm_insn ("\tl.lwz   \t%H0, %1+4(%2)", xoperands);
    > output_asm_insn ("\tl.lwz   \t%0, %1(%2)", xoperands);
    > return "";
    > }
    > else
    > {
    > output_asm_insn ("\tl.lwz   \t%0, %1(%2)", xoperands);
    > output_asm_insn ("\tl.lwz   \t%H0, %1+4(%2)", xoperands);
    > return "";
    > }
    > }
    > else if (GET_CODE (xoperands[2] = XEXP (xoperands[1], 0)) == REG)
    > {
    > xoperands[0] = operands[0];
    > xoperands[1] = XEXP (xoperands[1], 1);
    > if (REGNO (xoperands[0]) == REGNO (xoperands[2]))
    >                                                 {
    >
    > output_asm_insn ("\tl.lwz   \t%H0, %1+4(%2)", xoperands);
    >
    > output_asm_insn ("\tl.lwz   \t%0, %1(%2)", xoperands);
    >                                                         return "";
    >                                                 }
    > else
    >                                                 {
    >
    > output_asm_insn ("\tl.lwz   \t%0, %1(%2)", xoperands);
    >
    > output_asm_insn ("\tl.lwz   \t%H0, %1+4(%2)", xoperands);
    >                                                         return "";
    >                                                 }
    > }
    > else abort ();
    > }
    > else abort ();
    > }
    > else if (GET_CODE (operands[1]) == CONST_INT)
    > {
    > if (INTVAL (operands[1]) < 0)
    > output_asm_insn ("\tl.addi  \t%0, r0, -1", operands);
    > else
    > output_asm_insn ("\tl.or    \t%0, r0, r0", operands);
    > output_asm_insn ("\tl.movhi \t%H0, hi(%1)", operands);
    > output_asm_insn ("\tl.ori   \t%H0, %H0, lo(%1)", operands);
    > return "";
    > }
    > else abort ();
    > case MEM:
    > xoperands[0] = XEXP (operands[0], 0);
    > if (GET_CODE (xoperands[0]) == REG)
    > {
    > xoperands[1] = operands[1];
    > output_asm_insn ("\tl.sw    \t0(%0), %1", xoperands);
    > output_asm_insn ("\tl.sw    \t4(%0), %H1", xoperands);
    > return "";
    > }
    > else if (GET_CODE (xoperands[0]) == PLUS)
    > {
    > if (GET_CODE (xoperands[1] = XEXP (xoperands[0], 1)) == REG)
    > {
    > xoperands[0] = XEXP (xoperands[0], 0);
    > xoperands[2] = operands[1];
    > output_asm_insn ("\tl.sw    \t%0(%1), %2", xoperands);
    > output_asm_insn ("\tl.sw    \t%0+4(%1), %H2", xoperands);
    > return "";
    > }
    > else if (GET_CODE (xoperands[1] = XEXP (xoperands[0], 0)) == REG)
    > {
    > xoperands[0] = XEXP (xoperands[0], 1);
    > xoperands[2] = operands[1];
    > output_asm_insn ("\tl.sw    \t%0(%1), %2", xoperands);
    > output_asm_insn ("\tl.sw    \t%0+4(%1), %H2", xoperands);
    > return "";
    > }
    > else abort ();
    > }
    > else abort ();
    > default:
    > abort ();
    > }
    > }
    >
    >
    > Following with or32.md, I think that "movdi" should be defined. The
    > definition is similar to "movdf" :
    >
    >      (define_insn "movdi"
    >              [(set (match_operand:DI 0 "nonimmediate_operand" "=r, r,
    > m, r")
    >                    (match_operand:DI 1 "general_operand"      " r, m,
    > r, i"))]
    >              ""
    >              "*
    >               return or1k_output_move_double (operands);
    >              "
    >              [(set_attr "length" "2,2,2,3")])
    >
    > Also in or32.md I think you should define "addi3". The definition
    > should be:
    >
    >      (define_insn "adddi3"
    >              [(set (match_operand:DI 0 "register_operand" "=&r")
    >                    (plus:DI (match_operand:DI 1 "register_operand" "%r")
    >                              (match_operand:DI 2 "register_operand" "
    > r")))]
    >              ""
    >              "*
    >               return or1k_output_add_double (operands);
    >              "
    >              [(set_attr "length" "2")])
    >
    > The definition of or1k_output_add_double(operands) must be put in or1k.c:
    >
    > char *
    > or1k_output_add_double (rtx *operands)
    >
    > {
    > if (REGNO (operands[0]) + 1 == REGNO (operands[1]))
    > {
    > output_asm_insn ("\tl.add   \t%0, %H1, %H2", operands);
    > output_asm_insn ("\tl.addc  \t%0, %1, %2", operands);
    > output_asm_insn ("\tl.add   \t%H0, %H1, %H2", operands);
    > }
    > else
    > {
    > output_asm_insn ("\tl.add   \t%H0, %H1, %H2", operands);
    > output_asm_insn ("\tl.addc  \t%0, %1, %2", operands);
    > }
    > return "";
    > }
    >
    > That's all the changes that must be done in or32.md. I think that this
    > changes will solve most of the optimization problems. I don't have
    > tested it with GCC 3.2.3, but in 3.4 they work fine.
    >
    > Now, changes I think that must be made in or32.S:
    >
    > If the ABI has not changed since the last time, Calle-Saved Registers
    > are: r10, r13, r15, r17, r19, r21, r23, r25, r27, r29 and r31, so if
    > you use them inside a function call, you should save them at function
    > entry and restore them at function exit, so in file or32.S you should do:
    >
    >    in function ___udivsi3, the instruction "l.addi          r13,r0,32"
    >  should use another register (r12 for example) instead of r13, or you
    > should save r13 in function entry for restoring it in function exit.
    > The same happens with registers r15 and r17 in manay instructions. I
    > think that the easiest way to solve that problem is to replace every
    > usage of r13 for r12, r15 for r14, and r17 for r16.
    >
    > Anything else at the moment.
    >
    > Bestb regards,
    >
    > Pablo Huerta
    >
    > ----- Original Message ----- 
    > From: Matjaz Breskvar <phoenix@f... >
    > To: openrisc@o...
    > Date: Wed, 12 Nov 2003 13:22:48 +0100
    > Subject: Re: [openrisc] Optimization Problems
    >
    > >
    > >
    > > * pablo.huerta@a...  (pablo.huerta@a... )
    > > wrote:
    > > > Hi all!
    > > >
    > > > I have read some messages about optimization problems when
    > > using GCC
    > > > 3.2.3. In
    > > >
    > >
    >
    http://www.teisa.unican.es/~csanchez/guides/double_modes_bug_explanation.shtml
    >
    > > > there is an explanation on how we solved a bug with
    > > optimization
    > > > problems in GCC 2.9.5 that is not solved yet in GCC 3.2.3,
    > > reading
    > > > this may help OpenCores GCC maintainers to solve this
    > > problems.
    > >
    > > i'll look into this and fix it.
    > >
    > > > If any GCC maintainer needs help to solve that problem, I can
    > > help
    > > > him. I have also found   some problems in file or32.S, in the
    > > > __udivsi3 function. I think that functions in or32.S file
    > > should be
    > > > revised. I don't have write acces to CVS so if any maintainer
    > > could
    > > > help me to solve that bugs please contact me.
    > >
    > > i'm defenetly interested in fixing any/all bugs in OpenRISC
    > > toolchain.
    > > please do post any bugs you've found with proposed bugfixes.
    > >
    > > > Also we have already developed the port of GCC 3.4 and will be
    > > ready
    > > > for downloading in that web page soon:
    > > > http://www.teisa.unican.es/~csanchez/download1.shtml A port of
    > > eCos 2.0
    > > > is also ready to be published. I will post a message in the
    > > forum when
    > > > everythingh is ready to download.
    > >
    > > please make sure that your gcc-3.4 port uses the same ABI
    > > than ours. one quick test would be to compile uclinux from
    > > opencores
    > > cvs. i think it's in all ours best interest to have one unified
    > > toolchain
    > > to avoid duplicating efforts.
    > >
    > > regards,
    > > p.
    > >
    > 
    
    
    
    

    ReferenceAuthor
    Re: [openrisc] Optimization ProblemsPablo huerta

     
    Copyright (c) 1999 OPENCORES.ORG. All rights reserved.