aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/X86/X86CallingConv.td15
1 files changed, 8 insertions, 7 deletions
diff --git a/lib/Target/X86/X86CallingConv.td b/lib/Target/X86/X86CallingConv.td
index 6924520ab8..7f99203a83 100644
--- a/lib/Target/X86/X86CallingConv.td
+++ b/lib/Target/X86/X86CallingConv.td
@@ -22,13 +22,14 @@ class CCIfSubtarget<string F, CCAction A>
// Return-value conventions common to all X86 CC's.
def RetCC_X86Common : CallingConv<[
- // Scalar values are returned in AX first, then DX, except for i8 where
- // the convention is to return values in AL and AH. However, using AL and
- // AH is problematic -- a return of {i16,i8} would end up using AX and AH,
- // and one value would clobber the other. C front-ends are currently expected
- // to pack two i8 values into an i16 in the rare situations where this
- // is necessary.
- CCIfType<[i8] , CCAssignToReg<[AL]>>,
+ // Scalar values are returned in AX first, then DX. For i8, the ABI
+ // requires the values to be in AL and AH, however this code uses AL and DL
+ // instead. This is because using AH for the second register conflicts with
+ // the way LLVM does multiple return values -- a return of {i16,i8} would end
+ // up in AX and AH, which overlap. Front-ends wishing to conform to the ABI
+ // for functions that return two i8 values are currently expected to pack the
+ // values into an i16 (which uses AX, and thus AL:AH).
+ CCIfType<[i8] , CCAssignToReg<[AL, DL]>>,
CCIfType<[i16], CCAssignToReg<[AX, DX]>>,
CCIfType<[i32], CCAssignToReg<[EAX, EDX]>>,
CCIfType<[i64], CCAssignToReg<[RAX, RDX]>>,