diff --git a/lib/Target/Mips/MipsCallingConv.td b/lib/Target/Mips/MipsCallingConv.td index bf7162f224b..615310fbf70 100644 --- a/lib/Target/Mips/MipsCallingConv.td +++ b/lib/Target/Mips/MipsCallingConv.td @@ -192,8 +192,15 @@ def CC_Mips_FastCC : CallingConv<[ // Integer arguments are passed in integer registers. All scratch registers, // except for AT, V0 and T9, are available to be used as argument registers. - CCIfType<[i32], CCAssignToReg<[A0, A1, A2, A3, T0, T1, T2, T3, T4, T5, T6, - T7, T8, V1]>>, + CCIfType<[i32], CCIfSubtarget<"isNotTargetNaCl()", + CCAssignToReg<[A0, A1, A2, A3, T0, T1, T2, T3, T4, T5, T6, T7, T8, V1]>>>, + + // In NaCl, T6, T7 and T8 are reserved and not available as argument + // registers for fastcc. T6 contains the mask for sandboxing control flow + // (indirect jumps and calls). T7 contains the mask for sandboxing memory + // accesses (loads and stores). T8 contains the thread pointer. + CCIfType<[i32], CCIfSubtarget<"isTargetNaCl()", + CCAssignToReg<[A0, A1, A2, A3, T0, T1, T2, T3, T4, T5, V1]>>>, // f32 arguments are passed in single-precision floating pointer registers. CCIfType<[f32], CCAssignToReg<[F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, diff --git a/lib/Target/Mips/MipsRegisterInfo.cpp b/lib/Target/Mips/MipsRegisterInfo.cpp index 65b1f8cf2d1..14c96a06976 100644 --- a/lib/Target/Mips/MipsRegisterInfo.cpp +++ b/lib/Target/Mips/MipsRegisterInfo.cpp @@ -134,6 +134,13 @@ getReservedRegs(const MachineFunction &MF) const { for (unsigned I = 0; I < array_lengthof(ReservedGPR32); ++I) Reserved.set(ReservedGPR32[I]); + // Reserve registers for the NaCl sandbox. + if (Subtarget.isTargetNaCl()) { + Reserved.set(Mips::T6); // Reserved for control flow mask. + Reserved.set(Mips::T7); // Reserved for memory access mask. + Reserved.set(Mips::T8); // Reserved for thread pointer. + } + for (unsigned I = 0; I < array_lengthof(ReservedGPR64); ++I) Reserved.set(ReservedGPR64[I]); diff --git a/lib/Target/Mips/MipsSubtarget.h b/lib/Target/Mips/MipsSubtarget.h index f8fcef4588d..ba1e1452d24 100644 --- a/lib/Target/Mips/MipsSubtarget.h +++ b/lib/Target/Mips/MipsSubtarget.h @@ -209,6 +209,7 @@ public: bool os16() const { return Os16;}; bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); } + bool isNotTargetNaCl() const { return !TargetTriple.isOSNaCl(); } // for now constant islands are on for the whole compilation unit but we only // really use them if in addition we are in mips16 mode diff --git a/test/CodeGen/Mips/fastcc.ll b/test/CodeGen/Mips/fastcc.ll index 82919e7139b..8ee7af88c6b 100644 --- a/test/CodeGen/Mips/fastcc.ll +++ b/test/CodeGen/Mips/fastcc.ll @@ -1,4 +1,7 @@ ; RUN: llc < %s -march=mipsel | FileCheck %s +; RUN: llc < %s -mtriple=mipsel-none-nacl-gnu \ +; RUN: | FileCheck %s -check-prefix=CHECK-NACL + @gi0 = external global i32 @gi1 = external global i32 @@ -95,6 +98,11 @@ entry: ; CHECK: lw $5 ; CHECK: lw $4 +; t6, t7 and t8 are reserved in NaCl and cannot be used for fastcc. +; CHECK-NACL-NOT: lw $14 +; CHECK-NACL-NOT: lw $15 +; CHECK-NACL-NOT: lw $24 + %0 = load i32* @gi0, align 4 %1 = load i32* @gi1, align 4 %2 = load i32* @gi2, align 4 @@ -134,6 +142,11 @@ entry: ; CHECK: sw $24 ; CHECK: sw $3 +; t6, t7 and t8 are reserved in NaCl and cannot be used for fastcc. +; CHECK-NACL-NOT: sw $14 +; CHECK-NACL-NOT: sw $15 +; CHECK-NACL-NOT: sw $24 + store i32 %a0, i32* @g0, align 4 store i32 %a1, i32* @g1, align 4 store i32 %a2, i32* @g2, align 4 diff --git a/test/CodeGen/Mips/nacl-reserved-regs.ll b/test/CodeGen/Mips/nacl-reserved-regs.ll new file mode 100644 index 00000000000..ae21283b1fb --- /dev/null +++ b/test/CodeGen/Mips/nacl-reserved-regs.ll @@ -0,0 +1,51 @@ +; RUN: llc -march=mipsel -O3 < %s | FileCheck %s +; RUN: llc -mtriple=mipsel-none-nacl-gnu -O3 < %s \ +; RUN: | FileCheck %s -check-prefix=CHECK-NACL + +@var = external global i32 + +define void @f() { + %val1 = load volatile i32* @var + %val2 = load volatile i32* @var + %val3 = load volatile i32* @var + %val4 = load volatile i32* @var + %val5 = load volatile i32* @var + %val6 = load volatile i32* @var + %val7 = load volatile i32* @var + %val8 = load volatile i32* @var + %val9 = load volatile i32* @var + %val10 = load volatile i32* @var + %val11 = load volatile i32* @var + %val12 = load volatile i32* @var + %val13 = load volatile i32* @var + %val14 = load volatile i32* @var + %val15 = load volatile i32* @var + %val16 = load volatile i32* @var + store volatile i32 %val1, i32* @var + store volatile i32 %val2, i32* @var + store volatile i32 %val3, i32* @var + store volatile i32 %val4, i32* @var + store volatile i32 %val5, i32* @var + store volatile i32 %val6, i32* @var + store volatile i32 %val7, i32* @var + store volatile i32 %val8, i32* @var + store volatile i32 %val9, i32* @var + store volatile i32 %val10, i32* @var + store volatile i32 %val11, i32* @var + store volatile i32 %val12, i32* @var + store volatile i32 %val13, i32* @var + store volatile i32 %val14, i32* @var + store volatile i32 %val15, i32* @var + store volatile i32 %val16, i32* @var + ret void + +; Check that t6, t7 and t8 are used in non-NaCl code. +; CHECK: lw $14 +; CHECK: lw $15 +; CHECK: lw $24 + +; t6, t7 and t8 are reserved in NaCl. +; CHECK-NACL-NOT: lw $14 +; CHECK-NACL-NOT: lw $15 +; CHECK-NACL-NOT: lw $24 +}