mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
Fix the remaining MUL8 and DIV8 to define AX instead of AL,AH.
These instructions technically define AL,AH, but a trick in X86ISelDAGToDAG reads AX in order to avoid reading AH with a REX instruction. Fix PR6489. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97742 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0ef701e6ae
commit
3cfe01072c
@ -1050,7 +1050,10 @@ def MOV32cr : I<0x22, MRMSrcReg, (outs CONTROL_REG_32:$dst), (ins GR32:$src),
|
||||
//
|
||||
|
||||
// Extra precision multiplication
|
||||
let Defs = [AL,AH,EFLAGS], Uses = [AL] in
|
||||
|
||||
// AL is really implied by AX, by the registers in Defs must match the
|
||||
// SDNode results (i8, i32).
|
||||
let Defs = [AL,EFLAGS,AX], Uses = [AL] in
|
||||
def MUL8r : I<0xF6, MRM4r, (outs), (ins GR8:$src), "mul{b}\t$src",
|
||||
// FIXME: Used for 8-bit mul, ignore result upper 8 bits.
|
||||
// This probably ought to be moved to a def : Pat<> if the
|
||||
@ -1068,7 +1071,7 @@ def MUL32r : I<0xF7, MRM4r, (outs), (ins GR32:$src),
|
||||
"mul{l}\t$src",
|
||||
[]>; // EAX,EDX = EAX*GR32
|
||||
|
||||
let Defs = [AL,AH,EFLAGS], Uses = [AL] in
|
||||
let Defs = [AL,EFLAGS,AX], Uses = [AL] in
|
||||
def MUL8m : I<0xF6, MRM4m, (outs), (ins i8mem :$src),
|
||||
"mul{b}\t$src",
|
||||
// FIXME: Used for 8-bit mul, ignore result upper 8 bits.
|
||||
@ -1090,7 +1093,7 @@ def MUL32m : I<0xF7, MRM4m, (outs), (ins i32mem:$src),
|
||||
}
|
||||
|
||||
let neverHasSideEffects = 1 in {
|
||||
let Defs = [AL,AH,EFLAGS], Uses = [AL] in
|
||||
let Defs = [AL,EFLAGS,AX], Uses = [AL] in
|
||||
def IMUL8r : I<0xF6, MRM5r, (outs), (ins GR8:$src), "imul{b}\t$src", []>;
|
||||
// AL,AH = AL*GR8
|
||||
let Defs = [AX,DX,EFLAGS], Uses = [AX] in
|
||||
@ -1100,7 +1103,7 @@ let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
|
||||
def IMUL32r : I<0xF7, MRM5r, (outs), (ins GR32:$src), "imul{l}\t$src", []>;
|
||||
// EAX,EDX = EAX*GR32
|
||||
let mayLoad = 1 in {
|
||||
let Defs = [AL,AH,EFLAGS], Uses = [AL] in
|
||||
let Defs = [AL,EFLAGS,AX], Uses = [AL] in
|
||||
def IMUL8m : I<0xF6, MRM5m, (outs), (ins i8mem :$src),
|
||||
"imul{b}\t$src", []>; // AL,AH = AL*[mem8]
|
||||
let Defs = [AX,DX,EFLAGS], Uses = [AX] in
|
||||
@ -1113,7 +1116,7 @@ def IMUL32m : I<0xF7, MRM5m, (outs), (ins i32mem:$src),
|
||||
} // neverHasSideEffects
|
||||
|
||||
// unsigned division/remainder
|
||||
let Defs = [AX,EFLAGS], Uses = [AX] in
|
||||
let Defs = [AL,EFLAGS,AX], Uses = [AX] in
|
||||
def DIV8r : I<0xF6, MRM6r, (outs), (ins GR8:$src), // AX/r8 = AL,AH
|
||||
"div{b}\t$src", []>;
|
||||
let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
|
||||
@ -1123,7 +1126,7 @@ let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
|
||||
def DIV32r : I<0xF7, MRM6r, (outs), (ins GR32:$src), // EDX:EAX/r32 = EAX,EDX
|
||||
"div{l}\t$src", []>;
|
||||
let mayLoad = 1 in {
|
||||
let Defs = [AL,AH,EFLAGS], Uses = [AX] in
|
||||
let Defs = [AL,EFLAGS,AX], Uses = [AX] in
|
||||
def DIV8m : I<0xF6, MRM6m, (outs), (ins i8mem:$src), // AX/[mem8] = AL,AH
|
||||
"div{b}\t$src", []>;
|
||||
let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
|
||||
@ -1136,7 +1139,7 @@ def DIV32m : I<0xF7, MRM6m, (outs), (ins i32mem:$src),
|
||||
}
|
||||
|
||||
// Signed division/remainder.
|
||||
let Defs = [AL,AH,EFLAGS], Uses = [AX] in
|
||||
let Defs = [AL,EFLAGS,AX], Uses = [AX] in
|
||||
def IDIV8r : I<0xF6, MRM7r, (outs), (ins GR8:$src), // AX/r8 = AL,AH
|
||||
"idiv{b}\t$src", []>;
|
||||
let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
|
||||
@ -1146,7 +1149,7 @@ let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
|
||||
def IDIV32r: I<0xF7, MRM7r, (outs), (ins GR32:$src), // EDX:EAX/r32 = EAX,EDX
|
||||
"idiv{l}\t$src", []>;
|
||||
let mayLoad = 1, mayLoad = 1 in {
|
||||
let Defs = [AL,AH,EFLAGS], Uses = [AX] in
|
||||
let Defs = [AL,EFLAGS,AX], Uses = [AX] in
|
||||
def IDIV8m : I<0xF6, MRM7m, (outs), (ins i8mem:$src), // AX/[mem8] = AL,AH
|
||||
"idiv{b}\t$src", []>;
|
||||
let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
|
||||
|
25
test/CodeGen/X86/2010-03-04-Mul8Bug.ll
Normal file
25
test/CodeGen/X86/2010-03-04-Mul8Bug.ll
Normal file
@ -0,0 +1,25 @@
|
||||
; RUN: llc < %s
|
||||
; PR6489
|
||||
;
|
||||
; This test case produces a MUL8 instruction and then tries to read the result
|
||||
; from the AX register instead of AH/AL. That confuses live interval analysis.
|
||||
;
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||
target triple = "x86_64-apple-darwin10.0.0"
|
||||
|
||||
define void @func_56(i64 %p_57, i32*** %p_58) nounwind ssp {
|
||||
for.end:
|
||||
%conv49 = trunc i32 undef to i8 ; <i8> [#uses=1]
|
||||
%div.i = udiv i8 %conv49, 5 ; <i8> [#uses=1]
|
||||
%conv51 = zext i8 %div.i to i32 ; <i32> [#uses=1]
|
||||
%call55 = call i32 @qux(i32 undef, i32 -2) nounwind ; <i32> [#uses=1]
|
||||
%rem.i = urem i32 %call55, -1 ; <i32> [#uses=1]
|
||||
%cmp57 = icmp uge i32 %conv51, %rem.i ; <i1> [#uses=1]
|
||||
%conv58 = zext i1 %cmp57 to i32 ; <i32> [#uses=1]
|
||||
%call85 = call i32 @func_35(i32*** undef, i32 undef, i32 %conv58, i32 1247, i32 0) nounwind ; <i32> [#uses=0]
|
||||
ret void
|
||||
}
|
||||
|
||||
declare i32 @func_35(i32***, i32, i32, i32, i32)
|
||||
|
||||
declare i32 @qux(i32, i32)
|
Loading…
Reference in New Issue
Block a user