I don't know that off the top of my head---the ISAs I'm familiar with are
either not microcoded, or use a micro-op assembler to generate all the
micro-ops (i.e., x86).  Have you looked at how ARM micro-ops are
constructed?  That's the one ISA that I believe is mostly not microcoded
but still has some microcode in it.

Though come to think of it, it may be as easy as just using a constant
where the other operands specify the machine code bitfield, if there's
syntax that allows that.

Steve


On Tue, Aug 2, 2016 at 1:54 PM Alec Roelke <[email protected]> wrote:

> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]>
>>> 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 <[email protected]> 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 <[email protected]>
>>>>> 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 <[email protected]>
>>>>>> 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, <[email protected]>
>>>>>>> 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 <[email protected]>
>>>>>>>> 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
>>>>>>>> > [email protected]
>>>>>>>> > 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
>>>>>>> [email protected]
>>>>>>> http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> gem5-users mailing list
>>>>>> [email protected]
>>>>>> http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users
>>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> gem5-users mailing list
>>>>> [email protected]
>>>>> http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users
>>>>
>>>>
>>>> _______________________________________________
>>>> gem5-users mailing list
>>>> [email protected]
>>>> http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users
>>>>
>>>
>>> _______________________________________________
>>> gem5-users mailing list
>>> [email protected]
>>> http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users
>>
>>
>> _______________________________________________
>> gem5-users mailing list
>> [email protected]
>> http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users
>>
>
> _______________________________________________
> gem5-users mailing list
> [email protected]
> http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users
_______________________________________________
gem5-users mailing list
[email protected]
http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users

Reply via email to