[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