llvm.org GIT mirror llvm / cf83621
[X86] Improve code size on X86 segment moves Moves of a value to a segment register from a 16-bit register is equivalent to one from it's corresponding 32-bit register. Match gas's behavior and rewrite instructions to the shorter of equivalent forms. Reviewers: rnk, ab Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D23166 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278031 91177308-0d34-0410-b5e6-96231b3b80d8 Nirav Dave 4 years ago
3 changed file(s) with 50 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
23302330 static_cast(*Operands[0]).setTokenValue(Repl);
23312331 }
23322332
2333 // Moving a 32 or 16 bit value into a segment register has the same
2334 // behavior. Modify such instructions to always take shorter form.
2335 if ((Name == "mov" || Name == "movw" || Name == "movl") &&
2336 (Operands.size() == 3)) {
2337 X86Operand &Op1 = (X86Operand &)*Operands[1];
2338 X86Operand &Op2 = (X86Operand &)*Operands[2];
2339 SMLoc Loc = Op1.getEndLoc();
2340 if (Op1.isReg() && Op2.isReg() &&
2341 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
2342 Op2.getReg()) &&
2343 (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.getReg()) ||
2344 X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.getReg()))) {
2345 // Change instruction name to match new instruction.
2346 if (Name != "mov" && Name[3] == (is16BitMode() ? 'l' : 'w')) {
2347 Name = is16BitMode() ? "movw" : "movl";
2348 Operands[0] = X86Operand::CreateToken(Name, NameLoc);
2349 }
2350 // Select the correct equivalent 16-/32-bit source register.
2351 unsigned Reg =
2352 getX86SubSuperRegisterOrZero(Op1.getReg(), is16BitMode() ? 16 : 32);
2353 Operands[1] = X86Operand::CreateReg(Reg, Loc, Loc);
2354 }
2355 }
2356
23332357 // This is a terrible hack to handle "out[s]?[bwl]? %al, (%dx)" ->
23342358 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
23352359 // documented form in various unofficial manuals, so a lot of code uses it.
255255 // CHECK: encoding: [0x67,0x8c,0x08]
256256 movw %cs, (%eax)
257257
258 // CHECK: movl %eax, %cs
259 // CHECK: encoding: [0x66,0x8e,0xc8]
258 // CHECK: movw %ax, %cs
259 // CHECK: encoding: [0x8e,0xc8]
260260 movl %eax, %cs
261261
262 // CHECK: movw %ax, %cs
263 // CHECK: encoding: [0x8e,0xc8]
264 mov %eax, %cs
265
266 // CHECK: movw %ax, %cs
267 // CHECK: encoding: [0x8e,0xc8]
268 movw %ax, %cs
269
270 // CHECK: movw %ax, %cs
271 // CHECK: encoding: [0x8e,0xc8]
272 mov %ax, %cs
273
262274 // CHECK: movl (%eax), %cs
263275 // CHECK: encoding: [0x67,0x66,0x8e,0x08]
264276 movl (%eax), %cs
366366 // CHECK: encoding: [0x8e,0xc8]
367367 movl %eax, %cs
368368
369 // CHECK: movl %eax, %cs
370 // CHECK: encoding: [0x8e,0xc8]
371 movw %ax, %cs
372
373 // CHECK: movl %eax, %cs
374 // CHECK: encoding: [0x8e,0xc8]
375 mov %eax, %cs
376
377 // CHECK: movl %eax, %cs
378 // CHECK: encoding: [0x8e,0xc8]
379 mov %ax, %cs
380
369381 // CHECK: movl (%eax), %cs
370382 // CHECK: encoding: [0x8e,0x08]
371383 movl (%eax), %cs