Okay, thanks. How do I tell the ISA parser that the 'Rt' operand I've created refers to the extra architectural register? Or is there some function I can call inside the instruction's code that writes directly to an architectural register? All I can see from the code GEM5 generates is "setIntRegOperand," which takes indices into _destRegIdx rather than register indices.
On Mon, Aug 1, 2016 at 10:58 AM, Steve Reinhardt <ste...@gmail.com> wrote: > You don't need to worry about the size of the bitfield in the instruction > encoding, because the temporary register(s) will never be directly > addressed by any machine instruction. You should define a new > architectural register using an index that doesn't appear in any > instruction (e.g., if the ISA includes r0 to r31, then the temp reg can be > r32). This register will get renamed in the O3 model. > > Steve > > > On Sun, Jul 31, 2016 at 7:21 AM Alec Roelke <ar...@virginia.edu> wrote: > >> That makes sense. Would it be enough for me to just create a new IntReg >> operand, like this: >> >> 'Rt': ('IntReg', 'ud', None, 'IsInteger', 4) >> >> and then increase the number of integer registers? The other integer >> operands have a bit field from the instruction bits, but since the ISA >> doesn't specify that these RMW instructions should be microcoded, there's >> no way to decode a temporary register from the instruction bits. Will GEM5 >> understand that and pick any integer register that's available? >> >> The memory address is taken from Rs1 before the load micro-op, and then >> stored in a C++ variable for the remainder of the instruction. That was >> done to ensure that other intervening instructions that might get executed >> in the O3 model don't change Rs1 between the load and modify-write >> micro-ops, but if I can get the temp register to work then that might fix >> itself. >> >> I was only setting _srcRegIdx and _destRegIdx for disassembly reasons; >> since the macro-op and first micro-op don't make use of Rs2, the >> instruction wasn't setting _srcRegIdx[1] and the disassembly would show >> something like 4294967295. Then it presented a potential solution to the >> minor CPU model problem I described before. >> >> No, most of the ISA is not microcoded. In fact, as I said, these RMW >> instructions are not specified to be microcoded by the ISA, but since they >> each have two memory transactions they didn't appear to work unless I split >> them into two micro-ops. >> >> On Sat, Jul 30, 2016 at 2:14 PM, Steve Reinhardt <ste...@gmail.com> >> wrote: >> >>> You shouldn't be passing values between micro-ops using C++ variables, >>> you should pass the data in a register. (If necessary, create >>> microcode-only temporary registers for this purpose, like x86 does.) This >>> is microarchitectural state so you can't hide it from the CPU model. The >>> main problem here is that, since this "hidden" data dependency isn't >>> visible to the CPU model, it doesn't know that the micro-ops must be >>> executed in order. If you pass that data in a register, the pipeline model >>> will enforce the dependency. >>> >>> Also, where do you set the address for the memory accesses? Again, both >>> micro-ops should read that out of a register, it should not be passed >>> implicitly via hidden variables. >>> >>> You shouldn't have to explicitly set the internal fields like _srcRegIdx >>> and _destRegIdx, the ISA parser should do that for you. >>> >>> Unfortunately the ISA description system wasn't originally designed to >>> support microcode, and that support was kind of shoehorned in after the >>> fact, so it is a little messy. Is your whole ISA microcoded, or just a few >>> specific instructions? >>> >>> Steve >>> >>> >>> On Fri, Jul 29, 2016 at 7:37 PM Alec Roelke <ar...@virginia.edu> wrote: >>> >>>> Sure, I can show some code snippets. First, here is the code for the >>>> read micro-op for an atomic read-add-write: >>>> >>>> temp = Mem_sd; >>>> >>>> And the modify-write micro-op: >>>> >>>> Rd_sd = temp; >>>> Mem_sd = Rs2_sd + temp; >>>> >>>> The memory address comes from Rs1. The variable "temp" is a temporary >>>> location shared between the read and modify-write micro-ops (the address >>>> from Rs1 is shared similarly to ensure it's the same when the instructions >>>> are issued). >>>> >>>> In the constructor for the macro-op, I've included some code that >>>> explicitly sets the src and dest register indices so that they are >>>> displayed properly for execution traces: >>>> >>>> _numSrcRegs = 2; >>>> _srcRegIdx[0] = RS1; >>>> _srcRegIdx[1] = RS2; >>>> _numDestRegs = 1; >>>> _destRegIdx[0] = RD; >>>> >>>> So far, this works for the O3 model. But, in the minor model, it tries >>>> to execute the modify-write micro-op before the read micro-op is executed. >>>> The address is never loaded from Rs1, and so a segmentation fault often >>>> occurs. To try to fix it, I added this code to the constructors of each of >>>> the two micro-ops: >>>> >>>> _numSrcRegs = _p->_numSrcRegs; >>>> for (int i = 0; i < _numSrcRegs; i++) >>>> _srcRegIdx[i] = _p->_srcRegIdx[i]; >>>> _numDestRegs = _p->_numDestRegs; >>>> for (int i = 0; i < _numDestRegs; i++) >>>> _destRegIdx[i] = _p->_destRegIdx[i]; >>>> >>>> _p is a pointer to the "parent" macro-op. With this code, it works >>>> with minor model, but the final calculated value in the modify-write >>>> micro-op never gets written at the end of the instruction in the O3 model. >>>> >>>> >>>> On Fri, Jul 29, 2016 at 2:50 PM, Steve Reinhardt <ste...@gmail.com> >>>> wrote: >>>> >>>>> I'm still confused about the problems you're having. Stores should >>>>> never be executed speculatively in O3, even without the non-speculative >>>>> flag. Also, assuming the store micro-op reads a register that is written >>>>> by the load micro-op, then that true data dependence through the >>>>> intermediate register should enforce an ordering. Whether that >>>>> destination >>>>> register is also a source or not should be irrelevant, particularly in O3 >>>>> where all the registers get renamed anyway. >>>>> >>>>> Perhaps if you show some snippets of your actual code it will be >>>>> clearer to me what's going on. >>>>> >>>>> Steve >>>>> >>>>> >>>>> On Fri, Jul 29, 2016 at 9:33 AM Alec Roelke <ar...@virginia.edu> >>>>> wrote: >>>>> >>>>>> Yes, that sums up my issues. I haven't gotten to tackling the second >>>>>> one yet; I'm still working on the first. Thanks for the patch link, >>>>>> though, that should help a lot when I get to it. >>>>>> >>>>>> To be more specific, I can get it to work with either the minor CPU >>>>>> model or the O3 model, but not both at the same time. To get it to work >>>>>> with the O3 model, I added the "IsNonSpeculative" flag to the >>>>>> modify-write >>>>>> micro-op, which I assumed would prevent the O3 model from speculating on >>>>>> its execution (which I also had to do with regular store instructions to >>>>>> ensure that registers containing addresses would have the proper values >>>>>> when the instruction executed). This works, but when I use it in the >>>>>> minor >>>>>> CPU model, it issues the modify-write micro-op before the read micro-op >>>>>> executes, meaning it hasn't loaded the memory address from the register >>>>>> file yet and causes a segmentation fault. >>>>>> >>>>>> I assume this is caused by the fact that the code for the read >>>>>> operation doesn't reference any register, as the instruction writes the >>>>>> value that was read from memory to a dest register before modifying it >>>>>> and >>>>>> writing it back. Because the dest register can be the same as a source >>>>>> register, I have to pass the memory value from the read micro-op to the >>>>>> modify-write micro-op without writing it to a register to avoid >>>>>> potentially >>>>>> polluting the data written back. >>>>>> >>>>>> My fix was to explicitly set the source and dest registers of both >>>>>> micro-ops to what was decoded by the macro-op so GEM5 can infer >>>>>> dependencies, but then when I try it using the O3 model, the modify-write >>>>>> portion does not appear to actually write back to memory. >>>>>> >>>>>> On Fri, Jul 29, 2016 at 12:00 PM, <gem5-users-requ...@gem5.org> >>>>>> wrote: >>>>>> >>>>>>> There are really two issues here, I think: >>>>>>> >>>>>>> 1. Managing the ordering of the two micro-ops in the pipeline, which >>>>>>> seems >>>>>>> to be the issue you're facing. >>>>>>> 2. Providing atomicity when you have multiple cores. >>>>>>> >>>>>>> I'm surprised you're having problems with #1, because that's the >>>>>>> easy part. >>>>>>> I'd assume that you'd have a direct data dependency between the >>>>>>> micro-ops >>>>>>> (the load would write a register that the store reads, for the load >>>>>>> to pass >>>>>>> data to the store) which should enforce ordering. In addition, since >>>>>>> they're both accessing the same memory location, there shouldn't be >>>>>>> any >>>>>>> reordering of the memory operations either. >>>>>>> >>>>>>> Providing atomicity in the memory system is the harder part. The x86 >>>>>>> atomic >>>>>>> RMW memory ops are implemented by setting LOCKED_RMW on both the >>>>>>> load and >>>>>>> store operations (see >>>>>>> http://grok.gem5.org/source/xref/gem5/src/mem/request.hh#145, as >>>>>>> well >>>>>>> as src/arch/x86/isa/microops/ldstop.isa). This works with >>>>>>> AtomicSimpleCPU >>>>>>> and with Ruby, but there is no support for enforcing this atomicity >>>>>>> in the >>>>>>> classic cache in timing mode. I have a patch that provides this but >>>>>>> you >>>>>>> have to apply it manually: http://reviews.gem5.org/r/2691. >>>>>>> >>>>>>> Steve >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Wed, Jul 27, 2016 at 9:10 AM Alec Roelke <ar...@virginia.edu> >>>>>>> wrote: >>>>>>> >>>>>>> > Hello, >>>>>>> > >>>>>>> > I'm trying to add an ISA to gem5 which has several atomic >>>>>>> > read-modify-write instructions. Currently I have them implemented >>>>>>> as pairs >>>>>>> > of micro-ops which read data in the first operation and then >>>>>>> modify-write >>>>>>> > in the second. This works for the simple CPU model, but runs into >>>>>>> trouble >>>>>>> > for the minor and O3 models, which want to execute the >>>>>>> modify-write half >>>>>>> > before the load half is complete. I tried forcing both parts of >>>>>>> the >>>>>>> > instruction to have the same src and dest register indices, but >>>>>>> that causes >>>>>>> > other problems with the O3 model. >>>>>>> > >>>>>>> > Is there a way to indicate that there is a data dependency between >>>>>>> the two >>>>>>> > micro-ops in the instruction? Or, better yet, is there a way I >>>>>>> could >>>>>>> > somehow have two memory accesses in one instruction without having >>>>>>> to split >>>>>>> > it into micro-ops? >>>>>>> > >>>>>>> > Thanks, >>>>>>> > Alec Roelke >>>>>>> > _______________________________________________ >>>>>>> > gem5-users mailing list >>>>>>> > gem5-users@gem5.org >>>>>>> > http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users >>>>>>> >>>>>> -------------- next part -------------- >>>>>>> An HTML attachment was scrubbed... >>>>>>> URL: < >>>>>>> http://m5sim.org/cgi-bin/mailman/private/gem5-users/attachments/20160728/dc22e5dd/attachment-0001.html >>>>>>> > >>>>>>> >>>>>> _______________________________________________ >>>>>> gem5-users mailing list >>>>>> gem5-users@gem5.org >>>>>> http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users >>>>> >>>>> >>>>> _______________________________________________ >>>>> gem5-users mailing list >>>>> gem5-users@gem5.org >>>>> http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users >>>>> >>>> >>>> _______________________________________________ >>>> gem5-users mailing list >>>> gem5-users@gem5.org >>>> http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users >>> >>> >>> _______________________________________________ >>> gem5-users mailing list >>> gem5-users@gem5.org >>> http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users >>> >> >> _______________________________________________ >> gem5-users mailing list >> gem5-users@gem5.org >> http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users > > > _______________________________________________ > gem5-users mailing list > gem5-users@gem5.org > http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users >
_______________________________________________ gem5-users mailing list gem5-users@gem5.org http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users