My recollection of how all this works is that the arguments to the 'st'
micro-op get turned into arguments to a call to the StoreOp constructor:

   597 
<http://repo.gem5.org/gem5/file/cd7f3a1dbf55/src/arch/x86/isa/microops/ldstop.isa#l597>
        class StoreOp(LdStOp):
   598 
<http://repo.gem5.org/gem5/file/cd7f3a1dbf55/src/arch/x86/isa/microops/ldstop.isa#l598>
            def __init__(self, data, segment, addr, disp = 0,
   599 
<http://repo.gem5.org/gem5/file/cd7f3a1dbf55/src/arch/x86/isa/microops/ldstop.isa#l599>
                    dataSize="env.dataSize",
   600 
<http://repo.gem5.org/gem5/file/cd7f3a1dbf55/src/arch/x86/isa/microops/ldstop.isa#l600>
                    addressSize="env.addressSize",
   601 
<http://repo.gem5.org/gem5/file/cd7f3a1dbf55/src/arch/x86/isa/microops/ldstop.isa#l601>
                    atCPL0=False, nonSpec=False):

so the "-env.dataSize" you see is actually the displacement for the store,
not the dataSize or addressSize.  I think the problem is that the
addressSize is using the env,addressSize that's calculated the "normal"
way, i.e., including the effects of the override prefix.

Poking around some more, there's an 'ssz' symbol that maps to env.stackSize
[1] which gets used a lot in stack operations; for example, right after the
store in CALL_NEAR_I, 'ssz' is subtracted off of the stack pointer. The
calculation of env.stackSize seems to follow the rule you mentioned about
being fixed at 64 bits in 64-bit mode [2, 3].

So it might be sufficient to add ', addressSize=ssz' to the end of the 'st'
micro-op. Oddly though I don't see addressSize being set on any other stack
ops (just dataSize), so I wonder if this is a problem with other stack
instructions or not. If so, it might be useful to have an override
hardwired in at some lower level to check if the segment is ss and force
the address size to be stackSize (rather than adding this extra parameter
in a dozen different places). I wouldn't know where best to do that though,
so the manual override seems best for now.

Steve

[1] http://grok.gem5.org/xref/gem5/src/arch/x86/isa/microasm.isa#107
[2] http://grok.gem5.org/xref/gem5/src/arch/x86/isa.cc#91
[3] http://grok.gem5.org/xref/gem5/src/arch/x86/decoder.cc#400




On Mon, Jan 23, 2017 at 4:04 PM, Jason Lowe-Power <ja...@lowepower.com>
wrote:

> To those of you with more x86 ISA implementation knowledge than I have:
>
> I've been working through a bug one of our users found (thanks Sanchayan!).
> It looks like current versions of ld use the 0x67 instruction prefix
> (address size override) as an optimization instead of using a nop. See
> https://www.sourceware.org/ml/binutils/2016-05/msg00323.html.
>
> This causes the call instruction to be decoded with with the "address size
> override prefix", which is correct, in a sense. From what I can tell, this
> is passed to the call instruction via "-env.dataSize" (see call instruction
> implementation below).
>
> def macroop CALL_NEAR_I
> {
>     # Make the default data size of calls 64 bits in 64 bit mode
>     .adjust_env oszIn64Override
>     .function_call
>
>     limm t1, imm
>     rdip t7
>     # Check target of call
>     st t7, ss, [0, t0, rsp], "-env.dataSize"
>     subi rsp, rsp, ssz
>     wrip t7, t1
> };
>
> Now, the bug is, according to the x86 manual, "For instructions that
> implicitly access the stack segment (SS), the address size for stack
> accesses is determined by the D (default) bit in the stack-segment
> descriptor. In 64-bit mode, the D bit is ignored, and all stack references
> have a 64-bit address size." See
> https://support.amd.com/TechDocs/24594.pdf page
> 9.
>
> Thoughts on how to fix this?
>
> Thanks,
> Jason
> _______________________________________________
> gem5-dev mailing list
> gem5-dev@gem5.org
> http://m5sim.org/mailman/listinfo/gem5-dev
>
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to