We already divided out our classes as you did for ARM. The problem here is that we have a store/load byte/halfword to/from a Frame object. We know at that time that it's not going to be possible to store it using SP because there is only such instructions for store/load of a word. What we would want to do is to move SP into a Mips 16 register and then do a indexed load/store off of that register.when we finally create the load/store byte/word instruction. Hopefully then the aliased virtual register could be shared with other such virtual registers since SP does not change after the function prologue. gcc mips actually avoids this problem by always allocating one of the mips 16 registers as a sort of stack pointer, it's actually at a mid point in the functions stack frame. Reed On 09/24/2012 12:37 PM, Jim Grosbach wrote:> > On Sep 20, 2012, at 11:44 PM, Reed Kotler <rkotler at mips.com> wrote: > >> Actually, SP is already not in the mips 16 register class but there is some C++ code that is common to mips32, mips64 and mips16 that is wanting to use SP. It's kind of awkward but does work except in this case of load/store haflword and byte to stack objects. >> > > ARM has a similar problem. The InstrInfo classes should be factored out so that the targets have separate implementations where appropriate. See ARMBaseInstrInfo, ARMInstrInfo, Thumb1InstrInfo and Thumb2InstrInfo. Similarly, the FrameLowering classes. > > If you're sharing that code between the various targets, it sounds like there's some very significant architectural problems in your port, to be honest. > >> Maybe I'm shooting myself in the foot there. I don't know that code too well so maybe I need to look into it. >> >> There are some places where we use C++ code that I think we could use just td files or maybe in some cases add some small extensions to tablegen. >> >> Right now I'm just starting to debug and push upstream the whole mips 16 port and am at about 65% passing all single source and 25% of multi source tests. >> > > It really should have been developed directly on trunk rather than trying to push it upstream after the fact. Doing it this way is more pain for everyone. > >> >> On 09/20/2012 11:03 PM, Owen Anderson wrote: >>> Reed, >>> >>> It's not clear to me that you need to do anything special here. If you define your MIPS16 register class as not containing SP, then any MIPS16 instructions that get selected and want to read from SP should get a COPY inserted from SP to a MIPS16 vreg. The coalescer should, ideally, get rid of extraneous copies for you. >>> >>> --Owen >>> >>> >>> On Sep 20, 2012, at 10:48 PM, Reed Kotler <rkotler at mips.com> wrote: >>> >>>> Trying to think of a clever way to do something.... >>>> >>>> On Mips 16, the SP (stack pointer) is not a directly accessible register in most instructions. >>>> There is a way to move to and from mips 16 registers (subset of mips32) and mips32 registers. >>>> >>>> For the load/store word instructions, there are forms which implicitly take SP. >>>> >>>> However, for store/load byte and store/load halfword, there is no such instruction. >>>> >>>> In such cases, if I were writing assembly language code, I would move SP to a mips 16 register and then use it to do the store/load byte/haflword. >>>> >>>> It also then becomes a common subexpression because there may be multiple such accesses. >>>> >>>> It's like a temporary register alias. >>>> >>>> Add, Sub also have a way to reference memory using mips16 registers as a base address, so various operators on stack data are simplified. >>>> >>>> Any thoughts? >>>> >>>> Many ways to do this but I like simple ways. :) >>>> >>>> Tia. >>>> >>>> Reed >>>> >>>> _______________________________________________ >>>> LLVM Developers mailing list >>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >> >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Ok. That's a somewhat different problem, then. Devil will be in the details of what you want to do. A few options. First is to always have a standard frame pointer register available and reference off of that. Caveat: dynamic stack realignment and vararrays muck with that more than a bit. Second is what gcc is doing and reserve a register just for this in addition to the frame register. Possibly even better though is to use a plain virtual register and let the register allocator do its thing for materializing it when needed. There's a local frame allocation pass that is close to what you want that thumb uses to avoid rematerializing offsets all over the place. You could probably pattern something MIPS specific off of that as a starting point. ARM solves a similar issue by using the register scavenger to materialize immediates for frame indices that are out of range. In addition to any of the above you may need something similar. On Sep 25, 2012, at 9:34 PM, Reed Kotler <rkotler at mips.com> wrote:> We already divided out our classes as you did for ARM. > > The problem here is that we have a store/load byte/halfword to/from a Frame object. > > We know at that time that it's not going to be possible to store it using SP because there is only such instructions for store/load of a word. > > What we would want to do is to move SP into a Mips 16 register and then do a indexed load/store off of that register.when we finally create the load/store byte/word instruction. > > Hopefully then the aliased virtual register could be shared with other such virtual registers since SP does not change after the function prologue. > > gcc mips actually avoids this problem by always allocating one of the mips 16 registers as a sort of stack pointer, it's actually at a mid point in the functions stack frame. > > Reed > > On 09/24/2012 12:37 PM, Jim Grosbach wrote: >> >> On Sep 20, 2012, at 11:44 PM, Reed Kotler <rkotler at mips.com> wrote: >> >>> Actually, SP is already not in the mips 16 register class but there is some C++ code that is common to mips32, mips64 and mips16 that is wanting to use SP. It's kind of awkward but does work except in this case of load/store haflword and byte to stack objects. >>> >> >> ARM has a similar problem. The InstrInfo classes should be factored out so that the targets have separate implementations where appropriate. See ARMBaseInstrInfo, ARMInstrInfo, Thumb1InstrInfo and Thumb2InstrInfo. Similarly, the FrameLowering classes. >> >> If you're sharing that code between the various targets, it sounds like there's some very significant architectural problems in your port, to be honest. >> >>> Maybe I'm shooting myself in the foot there. I don't know that code too well so maybe I need to look into it. >>> >>> There are some places where we use C++ code that I think we could use just td files or maybe in some cases add some small extensions to tablegen. >>> >>> Right now I'm just starting to debug and push upstream the whole mips 16 port and am at about 65% passing all single source and 25% of multi source tests. >>> >> >> It really should have been developed directly on trunk rather than trying to push it upstream after the fact. Doing it this way is more pain for everyone. >> >>> >>> On 09/20/2012 11:03 PM, Owen Anderson wrote: >>>> Reed, >>>> >>>> It's not clear to me that you need to do anything special here. If you define your MIPS16 register class as not containing SP, then any MIPS16 instructions that get selected and want to read from SP should get a COPY inserted from SP to a MIPS16 vreg. The coalescer should, ideally, get rid of extraneous copies for you. >>>> >>>> --Owen >>>> >>>> >>>> On Sep 20, 2012, at 10:48 PM, Reed Kotler <rkotler at mips.com> wrote: >>>> >>>>> Trying to think of a clever way to do something.... >>>>> >>>>> On Mips 16, the SP (stack pointer) is not a directly accessible register in most instructions. >>>>> There is a way to move to and from mips 16 registers (subset of mips32) and mips32 registers. >>>>> >>>>> For the load/store word instructions, there are forms which implicitly take SP. >>>>> >>>>> However, for store/load byte and store/load halfword, there is no such instruction. >>>>> >>>>> In such cases, if I were writing assembly language code, I would move SP to a mips 16 register and then use it to do the store/load byte/haflword. >>>>> >>>>> It also then becomes a common subexpression because there may be multiple such accesses. >>>>> >>>>> It's like a temporary register alias. >>>>> >>>>> Add, Sub also have a way to reference memory using mips16 registers as a base address, so various operators on stack data are simplified. >>>>> >>>>> Any thoughts? >>>>> >>>>> Many ways to do this but I like simple ways. :) >>>>> >>>>> Tia. >>>>> >>>>> Reed >>>>> >>>>> _______________________________________________ >>>>> LLVM Developers mailing list >>>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>> >>> _______________________________________________ >>> LLVM Developers mailing list >>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
I thought of one solution. If we always copy SP to a virtual register during the function prologue, then if we see a use of addr in a store/load byte/halfword instruction, then we can change the register from SP to be this virtual register. Then I think that all the usual llvm optimizations will save us; i.e. the copy will never occur if the virtual register is not accessed and in addition the copy will get moved closer to the actual access. It makes intuitive sense to me to make the copy during the prologue, because that is when SP is modified. On 09/25/2012 09:34 PM, Reed Kotler wrote:> We already divided out our classes as you did for ARM. > > The problem here is that we have a store/load byte/halfword to/from a > Frame object. > > We know at that time that it's not going to be possible to store it > using SP because there is only such instructions for store/load of a word. > > What we would want to do is to move SP into a Mips 16 register and then > do a indexed load/store off of that register.when we finally create the > load/store byte/word instruction. > > Hopefully then the aliased virtual register could be shared with other > such virtual registers since SP does not change after the function > prologue. > > gcc mips actually avoids this problem by always allocating one of the > mips 16 registers as a sort of stack pointer, it's actually at a mid > point in the functions stack frame. > > Reed > > On 09/24/2012 12:37 PM, Jim Grosbach wrote: >> >> On Sep 20, 2012, at 11:44 PM, Reed Kotler <rkotler at mips.com> wrote: >> >>> Actually, SP is already not in the mips 16 register class but there >>> is some C++ code that is common to mips32, mips64 and mips16 that is >>> wanting to use SP. It's kind of awkward but does work except in this >>> case of load/store haflword and byte to stack objects. >>> >> >> ARM has a similar problem. The InstrInfo classes should be factored >> out so that the targets have separate implementations where >> appropriate. See ARMBaseInstrInfo, ARMInstrInfo, Thumb1InstrInfo and >> Thumb2InstrInfo. Similarly, the FrameLowering classes. >> >> If you're sharing that code between the various targets, it sounds >> like there's some very significant architectural problems in your >> port, to be honest. >> >>> Maybe I'm shooting myself in the foot there. I don't know that code >>> too well so maybe I need to look into it. >>> >>> There are some places where we use C++ code that I think we could use >>> just td files or maybe in some cases add some small extensions to >>> tablegen. >>> >>> Right now I'm just starting to debug and push upstream the whole mips >>> 16 port and am at about 65% passing all single source and 25% of >>> multi source tests. >>> >> >> It really should have been developed directly on trunk rather than >> trying to push it upstream after the fact. Doing it this way is more >> pain for everyone. >> >>> >>> On 09/20/2012 11:03 PM, Owen Anderson wrote: >>>> Reed, >>>> >>>> It's not clear to me that you need to do anything special here. If >>>> you define your MIPS16 register class as not containing SP, then any >>>> MIPS16 instructions that get selected and want to read from SP >>>> should get a COPY inserted from SP to a MIPS16 vreg. The coalescer >>>> should, ideally, get rid of extraneous copies for you. >>>> >>>> --Owen >>>> >>>> >>>> On Sep 20, 2012, at 10:48 PM, Reed Kotler <rkotler at mips.com> wrote: >>>> >>>>> Trying to think of a clever way to do something.... >>>>> >>>>> On Mips 16, the SP (stack pointer) is not a directly accessible >>>>> register in most instructions. >>>>> There is a way to move to and from mips 16 registers (subset of >>>>> mips32) and mips32 registers. >>>>> >>>>> For the load/store word instructions, there are forms which >>>>> implicitly take SP. >>>>> >>>>> However, for store/load byte and store/load halfword, there is no >>>>> such instruction. >>>>> >>>>> In such cases, if I were writing assembly language code, I would >>>>> move SP to a mips 16 register and then use it to do the store/load >>>>> byte/haflword. >>>>> >>>>> It also then becomes a common subexpression because there may be >>>>> multiple such accesses. >>>>> >>>>> It's like a temporary register alias. >>>>> >>>>> Add, Sub also have a way to reference memory using mips16 registers >>>>> as a base address, so various operators on stack data are simplified. >>>>> >>>>> Any thoughts? >>>>> >>>>> Many ways to do this but I like simple ways. :) >>>>> >>>>> Tia. >>>>> >>>>> Reed >>>>> >>>>> _______________________________________________ >>>>> LLVM Developers mailing list >>>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>> >>> _______________________________________________ >>> LLVM Developers mailing list >>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Thanks. Lots of good points. I will discuss this with Akira and come up with some definite solution. If it can work, I think that a combination of the local frame allocation pass and the virtual register copy of SP at the beginning of the function would be best. Maybe the local allocation pass is even optional. Mips 16 does not have a lot of easily usable registers and I don't want to do what gcc does and burn a whole register for each function to deal with this SP accessibility problem for load/store of chars and halfwords. I think that some of these Mips 16 problems really showcases some of the power of llvm over gcc. Even though this is the base port, I've already been able to make some nice improvements in code quality over gcc for mips16 just by good use of patterns in the td files. On 09/26/2012 12:00 AM, Jim Grosbach wrote:> Ok. That's a somewhat different problem, then. Devil will be in the details of what you want to do. A few options. First is to always have a standard frame pointer register available and reference off of that. Caveat: dynamic stack realignment and vararrays muck with that more than a bit. Second is what gcc is doing and reserve a register just for this in addition to the frame register. Possibly even better though is to use a plain virtual register and let the register allocator do its thing for materializing it when needed. There's a local frame allocation pass that is close to what you want that thumb uses to avoid rematerializing offsets all over the place. You could probably pattern something MIPS specific off of that as a starting point. > > > ARM solves a similar issue by using the register scavenger to materialize immediates for frame indices that are out of range. In addition to any of the above you may need something similar. > > On Sep 25, 2012, at 9:34 PM, Reed Kotler <rkotler at mips.com> wrote: > >> We already divided out our classes as you did for ARM. >> >> The problem here is that we have a store/load byte/halfword to/from a Frame object. >> >> We know at that time that it's not going to be possible to store it using SP because there is only such instructions for store/load of a word. >> >> What we would want to do is to move SP into a Mips 16 register and then do a indexed load/store off of that register.when we finally create the load/store byte/word instruction. >> >> Hopefully then the aliased virtual register could be shared with other such virtual registers since SP does not change after the function prologue. >> >> gcc mips actually avoids this problem by always allocating one of the mips 16 registers as a sort of stack pointer, it's actually at a mid point in the functions stack frame. >> >> Reed >> >> On 09/24/2012 12:37 PM, Jim Grosbach wrote: >>> >>> On Sep 20, 2012, at 11:44 PM, Reed Kotler <rkotler at mips.com> wrote: >>> >>>> Actually, SP is already not in the mips 16 register class but there is some C++ code that is common to mips32, mips64 and mips16 that is wanting to use SP. It's kind of awkward but does work except in this case of load/store haflword and byte to stack objects. >>>> >>> >>> ARM has a similar problem. The InstrInfo classes should be factored out so that the targets have separate implementations where appropriate. See ARMBaseInstrInfo, ARMInstrInfo, Thumb1InstrInfo and Thumb2InstrInfo. Similarly, the FrameLowering classes. >>> >>> If you're sharing that code between the various targets, it sounds like there's some very significant architectural problems in your port, to be honest. >>> >>>> Maybe I'm shooting myself in the foot there. I don't know that code too well so maybe I need to look into it. >>>> >>>> There are some places where we use C++ code that I think we could use just td files or maybe in some cases add some small extensions to tablegen. >>>> >>>> Right now I'm just starting to debug and push upstream the whole mips 16 port and am at about 65% passing all single source and 25% of multi source tests. >>>> >>> >>> It really should have been developed directly on trunk rather than trying to push it upstream after the fact. Doing it this way is more pain for everyone. >>> >>>> >>>> On 09/20/2012 11:03 PM, Owen Anderson wrote: >>>>> Reed, >>>>> >>>>> It's not clear to me that you need to do anything special here. If you define your MIPS16 register class as not containing SP, then any MIPS16 instructions that get selected and want to read from SP should get a COPY inserted from SP to a MIPS16 vreg. The coalescer should, ideally, get rid of extraneous copies for you. >>>>> >>>>> --Owen >>>>> >>>>> >>>>> On Sep 20, 2012, at 10:48 PM, Reed Kotler <rkotler at mips.com> wrote: >>>>> >>>>>> Trying to think of a clever way to do something.... >>>>>> >>>>>> On Mips 16, the SP (stack pointer) is not a directly accessible register in most instructions. >>>>>> There is a way to move to and from mips 16 registers (subset of mips32) and mips32 registers. >>>>>> >>>>>> For the load/store word instructions, there are forms which implicitly take SP. >>>>>> >>>>>> However, for store/load byte and store/load halfword, there is no such instruction. >>>>>> >>>>>> In such cases, if I were writing assembly language code, I would move SP to a mips 16 register and then use it to do the store/load byte/haflword. >>>>>> >>>>>> It also then becomes a common subexpression because there may be multiple such accesses. >>>>>> >>>>>> It's like a temporary register alias. >>>>>> >>>>>> Add, Sub also have a way to reference memory using mips16 registers as a base address, so various operators on stack data are simplified. >>>>>> >>>>>> Any thoughts? >>>>>> >>>>>> Many ways to do this but I like simple ways. :) >>>>>> >>>>>> Tia. >>>>>> >>>>>> Reed >>>>>> >>>>>> _______________________________________________ >>>>>> LLVM Developers mailing list >>>>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>>> >>>> _______________________________________________ >>>> LLVM Developers mailing list >>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>
Sorry.. this mail delivery is coming out of order for me. I sent one mail which replied to my earlier email and then afterwards got your email, which you sent 4 hours earlier but I had not received. Anyway, thanks for the hints. Akira and I will make a decision today and I'll check something in soon. Reed On 09/26/2012 12:00 AM, Jim Grosbach wrote:> Ok. That's a somewhat different problem, then. Devil will be in the details of what you want to do. A few options. First is to always have a standard frame pointer register available and reference off of that. Caveat: dynamic stack realignment and vararrays muck with that more than a bit. Second is what gcc is doing and reserve a register just for this in addition to the frame register. Possibly even better though is to use a plain virtual register and let the register allocator do its thing for materializing it when needed. There's a local frame allocation pass that is close to what you want that thumb uses to avoid rematerializing offsets all over the place. You could probably pattern something MIPS specific off of that as a starting point. > > > ARM solves a similar issue by using the register scavenger to materialize immediates for frame indices that are out of range. In addition to any of the above you may need something similar. > > On Sep 25, 2012, at 9:34 PM, Reed Kotler <rkotler at mips.com> wrote: > >> We already divided out our classes as you did for ARM. >> >> The problem here is that we have a store/load byte/halfword to/from a Frame object. >> >> We know at that time that it's not going to be possible to store it using SP because there is only such instructions for store/load of a word. >> >> What we would want to do is to move SP into a Mips 16 register and then do a indexed load/store off of that register.when we finally create the load/store byte/word instruction. >> >> Hopefully then the aliased virtual register could be shared with other such virtual registers since SP does not change after the function prologue. >> >> gcc mips actually avoids this problem by always allocating one of the mips 16 registers as a sort of stack pointer, it's actually at a mid point in the functions stack frame. >> >> Reed >> >> On 09/24/2012 12:37 PM, Jim Grosbach wrote: >>> On Sep 20, 2012, at 11:44 PM, Reed Kotler <rkotler at mips.com> wrote: >>> >>>> Actually, SP is already not in the mips 16 register class but there is some C++ code that is common to mips32, mips64 and mips16 that is wanting to use SP. It's kind of awkward but does work except in this case of load/store haflword and byte to stack objects. >>>> >>> ARM has a similar problem. The InstrInfo classes should be factored out so that the targets have separate implementations where appropriate. See ARMBaseInstrInfo, ARMInstrInfo, Thumb1InstrInfo and Thumb2InstrInfo. Similarly, the FrameLowering classes. >>> >>> If you're sharing that code between the various targets, it sounds like there's some very significant architectural problems in your port, to be honest. >>> >>>> Maybe I'm shooting myself in the foot there. I don't know that code too well so maybe I need to look into it. >>>> >>>> There are some places where we use C++ code that I think we could use just td files or maybe in some cases add some small extensions to tablegen. >>>> >>>> Right now I'm just starting to debug and push upstream the whole mips 16 port and am at about 65% passing all single source and 25% of multi source tests. >>>> >>> It really should have been developed directly on trunk rather than trying to push it upstream after the fact. Doing it this way is more pain for everyone. >>> >>>> On 09/20/2012 11:03 PM, Owen Anderson wrote: >>>>> Reed, >>>>> >>>>> It's not clear to me that you need to do anything special here. If you define your MIPS16 register class as not containing SP, then any MIPS16 instructions that get selected and want to read from SP should get a COPY inserted from SP to a MIPS16 vreg. The coalescer should, ideally, get rid of extraneous copies for you. >>>>> >>>>> --Owen >>>>> >>>>> >>>>> On Sep 20, 2012, at 10:48 PM, Reed Kotler <rkotler at mips.com> wrote: >>>>> >>>>>> Trying to think of a clever way to do something.... >>>>>> >>>>>> On Mips 16, the SP (stack pointer) is not a directly accessible register in most instructions. >>>>>> There is a way to move to and from mips 16 registers (subset of mips32) and mips32 registers. >>>>>> >>>>>> For the load/store word instructions, there are forms which implicitly take SP. >>>>>> >>>>>> However, for store/load byte and store/load halfword, there is no such instruction. >>>>>> >>>>>> In such cases, if I were writing assembly language code, I would move SP to a mips 16 register and then use it to do the store/load byte/haflword. >>>>>> >>>>>> It also then becomes a common subexpression because there may be multiple such accesses. >>>>>> >>>>>> It's like a temporary register alias. >>>>>> >>>>>> Add, Sub also have a way to reference memory using mips16 registers as a base address, so various operators on stack data are simplified. >>>>>> >>>>>> Any thoughts? >>>>>> >>>>>> Many ways to do this but I like simple ways. :) >>>>>> >>>>>> Tia. >>>>>> >>>>>> Reed >>>>>> >>>>>> _______________________________________________ >>>>>> LLVM Developers mailing list >>>>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>>> _______________________________________________ >>>> LLVM Developers mailing list >>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Turned out to be a rather simple fix. Just copied SP to a virtual register in the beginning of the function. Then added an extra operand to the DAGs with stack reference load/store, with the extra operand equal to this virtual register if the Parent of the address is a LOAD/STORE of an 8 or 16 bit quantity. It worked fine. When needed SP got copied to a mips 16 register and when the SP alias was not longer needed, the register was freed. I have a lot of mips 16 patches (3/4 of the port) to check in so this one may not be checked in for another week or two. There is probably an even cleaner way to do this (which I will be thinking about) but this worked. I'll take a look at the local frame allocation pass later. On 09/26/2012 12:00 AM, Jim Grosbach wrote:> Ok. That's a somewhat different problem, then. Devil will be in the details of what you want to do. A few options. First is to always have a standard frame pointer register available and reference off of that. Caveat: dynamic stack realignment and vararrays muck with that more than a bit. Second is what gcc is doing and reserve a register just for this in addition to the frame register. Possibly even better though is to use a plain virtual register and let the register allocator do its thing for materializing it when needed. There's a local frame allocation pass that is close to what you want that thumb uses to avoid rematerializing offsets all over the place. You could probably pattern something MIPS specific off of that as a starting point. > > > ARM solves a similar issue by using the register scavenger to materialize immediates for frame indices that are out of range. In addition to any of the above you may need something similar. > > On Sep 25, 2012, at 9:34 PM, Reed Kotler <rkotler at mips.com> wrote: > >> We already divided out our classes as you did for ARM. >> >> The problem here is that we have a store/load byte/halfword to/from a Frame object. >> >> We know at that time that it's not going to be possible to store it using SP because there is only such instructions for store/load of a word. >> >> What we would want to do is to move SP into a Mips 16 register and then do a indexed load/store off of that register.when we finally create the load/store byte/word instruction. >> >> Hopefully then the aliased virtual register could be shared with other such virtual registers since SP does not change after the function prologue. >> >> gcc mips actually avoids this problem by always allocating one of the mips 16 registers as a sort of stack pointer, it's actually at a mid point in the functions stack frame. >> >> Reed >> >> On 09/24/2012 12:37 PM, Jim Grosbach wrote: >>> >>> On Sep 20, 2012, at 11:44 PM, Reed Kotler <rkotler at mips.com> wrote: >>> >>>> Actually, SP is already not in the mips 16 register class but there is some C++ code that is common to mips32, mips64 and mips16 that is wanting to use SP. It's kind of awkward but does work except in this case of load/store haflword and byte to stack objects. >>>> >>> >>> ARM has a similar problem. The InstrInfo classes should be factored out so that the targets have separate implementations where appropriate. See ARMBaseInstrInfo, ARMInstrInfo, Thumb1InstrInfo and Thumb2InstrInfo. Similarly, the FrameLowering classes. >>> >>> If you're sharing that code between the various targets, it sounds like there's some very significant architectural problems in your port, to be honest. >>> >>>> Maybe I'm shooting myself in the foot there. I don't know that code too well so maybe I need to look into it. >>>> >>>> There are some places where we use C++ code that I think we could use just td files or maybe in some cases add some small extensions to tablegen. >>>> >>>> Right now I'm just starting to debug and push upstream the whole mips 16 port and am at about 65% passing all single source and 25% of multi source tests. >>>> >>> >>> It really should have been developed directly on trunk rather than trying to push it upstream after the fact. Doing it this way is more pain for everyone. >>> >>>> >>>> On 09/20/2012 11:03 PM, Owen Anderson wrote: >>>>> Reed, >>>>> >>>>> It's not clear to me that you need to do anything special here. If you define your MIPS16 register class as not containing SP, then any MIPS16 instructions that get selected and want to read from SP should get a COPY inserted from SP to a MIPS16 vreg. The coalescer should, ideally, get rid of extraneous copies for you. >>>>> >>>>> --Owen >>>>> >>>>> >>>>> On Sep 20, 2012, at 10:48 PM, Reed Kotler <rkotler at mips.com> wrote: >>>>> >>>>>> Trying to think of a clever way to do something.... >>>>>> >>>>>> On Mips 16, the SP (stack pointer) is not a directly accessible register in most instructions. >>>>>> There is a way to move to and from mips 16 registers (subset of mips32) and mips32 registers. >>>>>> >>>>>> For the load/store word instructions, there are forms which implicitly take SP. >>>>>> >>>>>> However, for store/load byte and store/load halfword, there is no such instruction. >>>>>> >>>>>> In such cases, if I were writing assembly language code, I would move SP to a mips 16 register and then use it to do the store/load byte/haflword. >>>>>> >>>>>> It also then becomes a common subexpression because there may be multiple such accesses. >>>>>> >>>>>> It's like a temporary register alias. >>>>>> >>>>>> Add, Sub also have a way to reference memory using mips16 registers as a base address, so various operators on stack data are simplified. >>>>>> >>>>>> Any thoughts? >>>>>> >>>>>> Many ways to do this but I like simple ways. :) >>>>>> >>>>>> Tia. >>>>>> >>>>>> Reed >>>>>> >>>>>> _______________________________________________ >>>>>> LLVM Developers mailing list >>>>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>>> >>>> _______________________________________________ >>>> LLVM Developers mailing list >>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>