[llvm] [llvm-exegesis] Add support for loading X86 segment registers (PR #76368)

Clement Courbet via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 26 00:20:39 PST 2023


================
@@ -907,9 +908,62 @@ void ExegesisX86Target::decrementLoopCounterAndJump(
       .addImm(X86::COND_NE);
 }
 
+void generateRegisterStackPush(unsigned int Register,
+                               std::vector<MCInst> &GeneratedCode) {
+  GeneratedCode.push_back(MCInstBuilder(X86::PUSH64r).addReg(Register));
+}
+
+void generateRegisterStackPop(unsigned int Register,
+                              std::vector<MCInst> &GeneratedCode) {
+  GeneratedCode.push_back(MCInstBuilder(X86::POP64r).addReg(Register));
+}
+
+void generateSyscall(long SyscallNumber, std::vector<MCInst> &GeneratedCode) {
+  GeneratedCode.push_back(
+      loadImmediate(X86::RAX, 64, APInt(64, SyscallNumber)));
+  GeneratedCode.push_back(MCInstBuilder(X86::SYSCALL));
+}
+
+static std::vector<MCInst> loadImmediateSegmentRegister(unsigned Reg,
+                                                        const APInt &Value) {
+  assert(Value.getBitWidth() <= 64 && "Value must fit in the register.");
+  std::vector<MCInst> loadSegmentRegisterCode;
+  // Preserve RCX and R11 (clobbered by the system call), and RAX, RDI, and RSI
+  // (used to make the system call). Preserve the registers here as we don't
+  // want to make any assumptions about the ordering of what registers are
+  // loaded in first, and we might have already loaded in registers that we are
+  // going to be clobbering here.
+  generateRegisterStackPush(X86::RAX, loadSegmentRegisterCode);
+  generateRegisterStackPush(X86::RDI, loadSegmentRegisterCode);
+  generateRegisterStackPush(X86::RSI, loadSegmentRegisterCode);
+  generateRegisterStackPush(X86::RCX, loadSegmentRegisterCode);
+  generateRegisterStackPush(X86::R11, loadSegmentRegisterCode);
+  // Generate the instructions to make the arch_prctl system call to set
+  // the registers.
+  assert(Reg == X86::FS ||
+         Reg == X86::GS &&
+             "Only the segment registers GS and FS are supported");
+  int SyscallCode = 0;
+  SyscallCode = Reg == X86::FS ? SyscallCode | ARCH_SET_FS : SyscallCode;
----------------
legrosbuffle wrote:

This is quite cryptic. Why not:

```
if (Reg == X86::FS) {
  SyscallCode = ARCH_SET_FS;
} else if (Reg == X86::GS) {
  SyscallCode = ARCH_SET_GS;
} else {
   llvm_unreacahble(...);
}
```

https://github.com/llvm/llvm-project/pull/76368


More information about the llvm-commits mailing list