This is an archive of the discontinued LLVM Phabricator instance.

Reduce x86 register context boilerplate.
ClosedPublic

Authored by labath on Dec 14 2017, 8:54 AM.

Details

Summary

The x86 FPR struct (which does not store just floating point registers)
was defined as a struct containing a union between two members: XSAVE
and FXSAVE. The initial layout of these two structs is identical, which
is recognised by the fact that XSAVE has FXSAVE as its first member.

This fact means that the whole union is not necessary and we can just
use XSAVE as our "fpr" struct. This reduced the amount of typing when
accessing the struct members and (I hope) makes code a bit cleaner.

Diff Detail

Repository
rL LLVM

Event Timeline

labath created this revision.Dec 14 2017, 8:54 AM

Personally I prefer the original code as it looks easier to implement FSAVE.

Personally I prefer the original code as it looks easier to implement FSAVE.

Also naming FPR is more logical, reusing the XSAVE name for 32-bit x86 looks wrong to me.

Personally I prefer the original code as it looks easier to implement FSAVE.

Maybe we could delete at least one layer then (make FPR a union which contains fxsave and xsave members)?

Also, I am curious: is your remark about FSAVE hypothetical or do you have plans about that? Is there an OS that vends registers in the FSAVE layout?

My feeling is that if you really wanted to implement the FSAVE layout you would run into a class of problems anyway, precisely because the layout is not the same as these two structures. (e.g. right now the way that the offset of the xmm registers is defined does not take into account whether you are using XSAVE or FXSAVE -- the only reason this works is because the two offsets are the same).

I want to support x86 CPUs in 32-bit mode starting from 486. At least to read core dumps.
This is the current bare minimum and tested setup by the releng team in NetBSD.

OpenBSD used to support 80386 with MMU, but not sure if this is still true after migration to Clang.

I've already implemented FPU checks in the existing code:

  • fpu_present (currently always on)
  • osfxsr
  • sse
  • sse2
  • fpu_save (fsave, fxsave, xsave, xsaveopt)
  • fpu_save_sze
  • xsave_features

Maybe reuse FPR for FXSAVE/FSAVE and add next to it XSAVE/XSAVE_OPT.

On NetBSD/i386 FPR registers are for FSAVE through GET_FPREGS/SET_FPREGS.

labath updated this revision to Diff 127111.Dec 15 2017, 5:35 AM

New version. This one keeps the fxsave/xsave distinction, but it makes FPR a
union directly, so it saves us one level of indirection.

Maybe reuse FPR for FXSAVE/FSAVE and add next to it XSAVE/XSAVE_OPT.

I am not sure what you mean by that, but I don't think it can work that way, as xsave area already contains a copy of the fpu registers, so we will end up having them twice. I have a feeling that for supporting fsave you will need to define your own register context (or just handle the transformation at a different layer -- this is how we avoided defining separate register context for minidumps -- we just rearrange the registers around to match the existing register context layout).

Maybe reuse FPR for FXSAVE/FSAVE and add next to it XSAVE/XSAVE_OPT.

I am not sure what you mean by that, but I don't think it can work that way, as xsave area already contains a copy of the fpu registers, so we will end up having them twice. I have a feeling that for supporting fsave you will need to define your own register context (or just handle the transformation at a different layer -- this is how we avoided defining separate register context for minidumps -- we just rearrange the registers around to match the existing register context layout).

I was thinking about split of FPU into two or more structs/unions.

But the newer version on review is better!

krytarowski accepted this revision.Dec 15 2017, 7:14 AM
This revision is now accepted and ready to land.Dec 15 2017, 7:14 AM
clayborg accepted this revision.Dec 15 2017, 2:34 PM

Looks good

This revision was automatically updated to reflect the committed changes.