changeset 17121:4a1ee9bebd33

Merge
author Stefan Anzinger <stefan.anzinger@oracle.com>
date Wed, 17 Sep 2014 08:23:54 -0700
parents 832c8c93c949 (diff) 8ca5e41dde86 (current diff)
children 62d7d16b170b 41368fb9ec1f
files
diffstat 8 files changed, 229 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Tue Sep 16 22:00:52 2014 +0200
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Wed Sep 17 08:23:54 2014 -0700
@@ -1515,6 +1515,8 @@
         Fones(0x7F, "fones"),
         Fandd(0b0_0111_0000, "fandd"),
         Fands(0b0_0111_0001, "fands"),
+        Fxord(0b0_0110_1100, "fxord"),
+        Fxors(0b0_0110_1101, "fxord"),
         // end VIS1
 
         // start VIS2
@@ -2197,7 +2199,7 @@
             super(0, ConditionFlag.Equal, Op2s.Bp, cc, predictTaken ? 1 : 0, label);
         }
 
-        public Bpe(boolean annul, CC cc, Label label, boolean predictTaken) {
+        public Bpe(CC cc, boolean annul, boolean predictTaken, Label label) {
             super(annul ? 1 : 0, ConditionFlag.Equal, Op2s.Bp, cc, predictTaken ? 1 : 0, label);
         }
 
@@ -3428,6 +3430,18 @@
         }
     }
 
+    public static class Fabss extends Fmt3p {
+        public Fabss(Register src2, Register dst) {
+            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fabss, SPARC.r0, src2, dst);
+        }
+    }
+
+    public static class Fabsd extends Fmt3p {
+        public Fabsd(Register src2, Register dst) {
+            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fabsd, SPARC.r0, src2, dst);
+        }
+    }
+
     public static class Fsrc1d extends Fmt3p {
 
         public Fsrc1d(Register src1, Register dst) {
@@ -4135,6 +4149,18 @@
         }
     }
 
+    public static class Fxord extends Fmt3p {
+        public Fxord(Register src1, Register src2, Register dst) {
+            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fxord, src1, src2, dst);
+        }
+    }
+
+    public static class Fxors extends Fmt3p {
+        public Fxors(Register src1, Register src2, Register dst) {
+            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fxors, src1, src2, dst);
+        }
+    }
+
     public static class Fands extends Fmt3p {
         public Fands(Register src1, Register src2, Register dst) {
             super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fands, src1, src2, dst);
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java	Tue Sep 16 22:00:52 2014 +0200
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java	Wed Sep 17 08:23:54 2014 -0700
@@ -44,11 +44,8 @@
 
     @Override
     public void align(int modulus) {
-        if (position() % modulus != 0) {
-            final int count = modulus - (position() % modulus);
-            for (int i = 0; i < count; i++) {
-                new Nop().emit(this);
-            }
+        while (position() % modulus != 0) {
+            new Nop().emit(this);
         }
     }
 
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Tue Sep 16 22:00:52 2014 +0200
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Wed Sep 17 08:23:54 2014 -0700
@@ -56,11 +56,13 @@
 import com.oracle.graal.lir.sparc.SPARCMove.LoadDataAddressOp;
 import com.oracle.graal.lir.sparc.SPARCMove.MembarOp;
 import com.oracle.graal.lir.sparc.SPARCMove.MoveFpGp;
+import com.oracle.graal.lir.sparc.SPARCMove.MoveFpGpVIS3;
 import com.oracle.graal.lir.sparc.SPARCMove.MoveFromRegOp;
 import com.oracle.graal.lir.sparc.SPARCMove.MoveToRegOp;
 import com.oracle.graal.lir.sparc.SPARCMove.StackLoadAddressOp;
 import com.oracle.graal.phases.util.*;
 import com.oracle.graal.sparc.*;
+import com.oracle.graal.sparc.SPARC.*;
 
 /**
  * This class implements the SPARC specific portion of the LIR generator.
@@ -409,9 +411,7 @@
     @Override
     public Value emitMathAbs(Value input) {
         Variable result = newVariable(LIRKind.derive(input));
-        AllocatableValue mask = newVariable(LIRKind.value(Kind.Double));
-        emitMove(mask, Constant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL)));
-        append(new BinaryRegReg(DAND, result, asAllocatable(input), mask));
+        append(new SPARCMathIntrinsicOp(ABS, result, asAllocatable(input)));
         return result;
     }
 
@@ -869,8 +869,12 @@
     }
 
     private void moveBetweenFpGp(AllocatableValue dst, AllocatableValue src) {
-        StackSlot tempSlot = getTempSlot(LIRKind.value(Kind.Long));
-        append(new MoveFpGp(dst, src, tempSlot));
+        if (!getArchitecture().getFeatures().contains(CPUFeature.VIS3)) {
+            StackSlot tempSlot = getTempSlot(LIRKind.value(Kind.Long));
+            append(new MoveFpGp(dst, src, tempSlot));
+        } else {
+            append(new MoveFpGpVIS3(dst, src));
+        }
     }
 
     private StackSlot getTempSlot(LIRKind kind) {
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Tue Sep 16 22:00:52 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Wed Sep 17 08:23:54 2014 -0700
@@ -76,13 +76,13 @@
 
     protected Set<CPUFeature> computeFeatures(HotSpotVMConfig config) {
         Set<CPUFeature> features = EnumSet.noneOf(CPUFeature.class);
-        if (config.vis1Instructions != 0) {
+        if ((config.sparcFeatures & config.vis1Instructions) != 0) {
             features.add(CPUFeature.VIS1);
         }
-        if (config.vis2Instructions != 0) {
+        if ((config.sparcFeatures & config.vis2Instructions) != 0) {
             features.add(CPUFeature.VIS2);
         }
-        if (config.vis3Instructions != 0) {
+        if ((config.sparcFeatures & config.vis3Instructions) != 0) {
             features.add(CPUFeature.VIS3);
         }
         return features;
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java	Tue Sep 16 22:00:52 2014 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java	Wed Sep 17 08:23:54 2014 -0700
@@ -129,7 +129,7 @@
     private void emit8ByteCompare(SPARCMacroAssembler masm, Register result, Register array1, Register array2, Register length, Label trueLabel, Label falseLabel) {
         Label loop = new Label();
         Label compareTail = new Label();
-
+        // new Ldx(new SPARCAddress(o6, 3), g0).emit(masm);
         Register tempReg1 = asRegister(temp4);
         Register tempReg2 = asRegister(temp5);
         new And(result, VECTOR_SIZE - 1, result).emit(masm); // tail count (in bytes)
@@ -137,27 +137,41 @@
         new Bpe(CC.Xcc, compareTail).emit(masm);
         new Nop().emit(masm);
 
+        Label compareTailCorrectVectorEnd = new Label();
+        new Sub(length, VECTOR_SIZE, length).emit(masm);
         new Add(array1, length, array1).emit(masm);
         new Add(array2, length, array2).emit(masm);
         new Sub(g0, length, length).emit(masm);
 
+        // Compare the last element first
+        new Ldx(new SPARCAddress(array1, 0), tempReg1).emit(masm);
+        new Ldx(new SPARCAddress(array2, 0), tempReg2).emit(masm);
+        new Cmp(tempReg1, tempReg2).emit(masm);
+        new Bpne(Xcc, true, false, falseLabel).emit(masm);
+        new Nop().emit(masm);
+        new Bpr(RCondition.Rc_z, false, false, length, compareTailCorrectVectorEnd).emit(masm);
+        new Nop().emit(masm);
+
         // Load the first value from array 1 (Later done in back branch delay-slot)
         new Ldx(new SPARCAddress(array1, length), tempReg1).emit(masm);
         masm.bind(loop);
         new Ldx(new SPARCAddress(array2, length), tempReg2).emit(masm);
-
         new Cmp(tempReg1, tempReg2).emit(masm);
         new Bpne(Xcc, false, false, falseLabel).emit(masm);
         // Delay slot, not annul, add for next iteration
-        new Add(length, VECTOR_SIZE, length).emit(masm);
-
-        new Bpr(RCondition.Rc_nz, true, true, length, loop).emit(masm);
+        new Addcc(length, VECTOR_SIZE, length).emit(masm);
+        new Bpne(Xcc, true, true, loop).emit(masm); // Annul, to prevent access past the array
         new Ldx(new SPARCAddress(array1, length), tempReg1).emit(masm); // Load in delay slot
 
         // Tail count zero, therefore we can go to the end
         new Bpr(RCondition.Rc_z, true, true, result, trueLabel).emit(masm);
         new Nop().emit(masm);
 
+        masm.bind(compareTailCorrectVectorEnd);
+        // Correct the array pointers
+        new Add(array1, VECTOR_SIZE, array1).emit(masm);
+        new Add(array2, VECTOR_SIZE, array2).emit(masm);
+
         masm.bind(compareTail);
     }
 
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java	Tue Sep 16 22:00:52 2014 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java	Wed Sep 17 08:23:54 2014 -0700
@@ -25,7 +25,7 @@
 import static com.oracle.graal.api.code.ValueUtil.*;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fsqrtd;
+import com.oracle.graal.asm.sparc.SPARCAssembler.*;
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.lir.*;
@@ -39,7 +39,8 @@
         COS,
         TAN,
         LOG,
-        LOG10
+        LOG10,
+        ABS
     }
 
     @Opcode private final IntrinsicOpcode opcode;
@@ -54,9 +55,31 @@
 
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+        Kind inputKind = (Kind) input.getLIRKind().getPlatformKind();
         switch (opcode) {
             case SQRT:
-                new Fsqrtd(asDoubleReg(input), asDoubleReg(result)).emit(masm);
+                switch (inputKind) {
+                    case Float:
+                        new Fsqrts(asFloatReg(input), asFloatReg(result)).emit(masm);
+                        break;
+                    case Double:
+                        new Fsqrtd(asDoubleReg(input), asDoubleReg(result)).emit(masm);
+                        break;
+                    default:
+                        GraalInternalError.shouldNotReachHere();
+                }
+                break;
+            case ABS:
+                switch (inputKind) {
+                    case Float:
+                        new Fabss(asFloatReg(input), asFloatReg(result)).emit(masm);
+                        break;
+                    case Double:
+                        new Fabsd(asDoubleReg(input), asDoubleReg(result)).emit(masm);
+                        break;
+                    default:
+                        GraalInternalError.shouldNotReachHere();
+                }
                 break;
             case LOG:
             case LOG10:
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Tue Sep 16 22:00:52 2014 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Wed Sep 17 08:23:54 2014 -0700
@@ -23,15 +23,46 @@
 package com.oracle.graal.lir.sparc;
 
 import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.api.meta.Kind.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 import static com.oracle.graal.sparc.SPARC.*;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.*;
 
 import com.oracle.graal.api.code.CompilationResult.RawData;
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Add;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Fmovd;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Fmovs;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Fxord;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Fxors;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Lddf;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Ldf;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsb;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsh;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsw;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Lduh;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Membar;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Movdtox;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Movstosw;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Movstouw;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Movwtos;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Movxtod;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Or;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Rdpc;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Stb;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Stdf;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Stf;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Sth;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Stw;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Stx;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cas;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Casx;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Clr;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.ImplicitNullCheck;
@@ -39,6 +70,7 @@
 import com.oracle.graal.lir.StandardOp.NullCheck;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.sparc.*;
+import com.oracle.graal.sparc.SPARC.CPUFeature;
 
 public class SPARCMove {
 
@@ -189,6 +221,61 @@
         }
     }
 
+    /**
+     * Move between floating-point and general purpose register domain (WITH VIS3)
+     */
+    @Opcode("MOVE")
+    public static class MoveFpGpVIS3 extends SPARCLIRInstruction implements MoveOp {
+
+        @Def({REG}) protected AllocatableValue result;
+        @Use({REG}) protected AllocatableValue input;
+
+        public MoveFpGpVIS3(AllocatableValue result, AllocatableValue input) {
+            super();
+            this.result = result;
+            this.input = input;
+        }
+
+        public Value getInput() {
+            return input;
+        }
+
+        public AllocatableValue getResult() {
+            return result;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            Kind inputKind = (Kind) input.getPlatformKind();
+            Kind resultKind = (Kind) result.getPlatformKind();
+            if (resultKind == Float) {
+                if (inputKind == Int || inputKind == Short || inputKind == Char || inputKind == Byte) {
+                    new Movwtos(asIntReg(input), asFloatReg(result)).emit(masm);
+                } else {
+                    throw GraalInternalError.shouldNotReachHere();
+                }
+            } else if (resultKind == Double) {
+                if (inputKind == Int || inputKind == Short || inputKind == Char || inputKind == Byte) {
+                    new Movxtod(asIntReg(input), asDoubleReg(result)).emit(masm);
+                } else {
+                    new Movxtod(asLongReg(input), asDoubleReg(result)).emit(masm);
+                }
+            } else if (inputKind == Float) {
+                if (resultKind == Int || resultKind == Short || resultKind == Byte) {
+                    new Movstosw(asFloatReg(input), asIntReg(result)).emit(masm);
+                } else {
+                    new Movstouw(asFloatReg(input), asIntReg(result)).emit(masm);
+                }
+            } else if (inputKind == Double) {
+                if (resultKind == Long) {
+                    new Movdtox(asDoubleReg(input), asLongReg(result)).emit(masm);
+                } else {
+                    throw GraalInternalError.shouldNotReachHere();
+                }
+            }
+        }
+    }
+
     public abstract static class MemOp extends SPARCLIRInstruction implements ImplicitNullCheck {
 
         protected final Kind kind;
@@ -655,6 +742,7 @@
     private static void const2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Constant input) {
         try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
             Register scratch = sc.getRegister();
+            boolean hasVIS3 = ((SPARC) masm.target.arch).getFeatures().contains(CPUFeature.VIS3);
             switch (input.getKind().getStackKind()) {
                 case Int:
                     if (input.isDefaultForKind()) {
@@ -674,28 +762,54 @@
                         new Setx(input.asLong(), asLongReg(result)).emit(masm);
                     }
                     break;
-                case Float:
-                    // TODO: Handle it the same way, as in the double case with Movwtos
-                    crb.asFloatConstRef(input);
-                    // First load the address into the scratch register
-                    new Setx(0, scratch, true).emit(masm);
-                    // Now load the float value
-                    new Ldf(scratch, asFloatReg(result)).emit(masm);
+                case Float: {
+                    float constant = input.asFloat();
+                    int constantBits = java.lang.Float.floatToIntBits(constant);
+                    if (constantBits == 0) {
+                        new Fxors(asFloatReg(result), asFloatReg(result), asFloatReg(result)).emit(masm);
+                    } else {
+                        if (hasVIS3) {
+                            if (isSimm13(constantBits)) {
+                                new Or(g0, constantBits, scratch).emit(masm);
+                            } else {
+                                new Setx(constantBits, scratch, false).emit(masm);
+                            }
+                            // Now load the float value
+                            new Movwtos(scratch, asFloatReg(result)).emit(masm);
+                        } else {
+                            crb.asFloatConstRef(input);
+                            // First load the address into the scratch register
+                            new Setx(0, scratch, true).emit(masm);
+                            // Now load the float value
+                            new Ldf(scratch, asFloatReg(result)).emit(masm);
+                        }
+                    }
                     break;
-                case Double:
-                    // instead loading this from memory and do the complicated lookup,
-                    // just load it directly into a scratch register
-                    // First load the address into the scratch register
-                    // new Setx(Double.doubleToLongBits(input.asDouble()), scratch,
-                    // true).emit(masm);
-                    // Now load the float value
-                    // new Movxtod(scratch, asDoubleReg(result)).emit(masm);
-                    crb.asDoubleConstRef(input);
-                    // First load the address into the scratch register
-                    new Setx(0, scratch, true).emit(masm);
-                    // Now load the float value
-                    new Lddf(scratch, asDoubleReg(result)).emit(masm);
+                }
+                case Double: {
+                    double constant = input.asDouble();
+                    long constantBits = java.lang.Double.doubleToLongBits(constant);
+                    if (constantBits == 0) {
+                        new Fxord(asDoubleReg(result), asDoubleReg(result), asDoubleReg(result)).emit(masm);
+                    } else {
+                        if (hasVIS3) {
+                            if (isSimm13(constantBits)) {
+                                new Or(g0, (int) constantBits, scratch).emit(masm);
+                            } else {
+                                new Setx(constantBits, scratch, false).emit(masm);
+                            }
+                            // Now load the float value
+                            new Movxtod(scratch, asDoubleReg(result)).emit(masm);
+                        } else {
+                            crb.asDoubleConstRef(input);
+                            // First load the address into the scratch register
+                            new Setx(0, scratch, true).emit(masm);
+                            // Now load the float value
+                            new Lddf(scratch, asDoubleReg(result)).emit(masm);
+                        }
+                    }
                     break;
+                }
                 case Object:
                     if (input.isNull()) {
                         new Clr(asRegister(result)).emit(masm);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/MathSubstitutionsX86.java	Tue Sep 16 22:00:52 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/MathSubstitutionsX86.java	Wed Sep 17 08:23:54 2014 -0700
@@ -33,7 +33,7 @@
 /**
  * Substitutions for {@link java.lang.Math} methods.
  */
-@ClassSubstitution(value = java.lang.Math.class, defaultGuard = UnsafeSubstitutions.GetAndSetGuard.class)
+@ClassSubstitution(value = java.lang.Math.class)
 public class MathSubstitutionsX86 {
 
     private static final double PI_4 = Math.PI / 4;
@@ -48,12 +48,12 @@
         return MathIntrinsicNode.compute(x, Operation.SQRT);
     }
 
-    @MethodSubstitution
+    @MethodSubstitution(guard = UnsafeSubstitutions.GetAndSetGuard.class)
     public static double log(double x) {
         return MathIntrinsicNode.compute(x, Operation.LOG);
     }
 
-    @MethodSubstitution
+    @MethodSubstitution(guard = UnsafeSubstitutions.GetAndSetGuard.class)
     public static double log10(double x) {
         return MathIntrinsicNode.compute(x, Operation.LOG10);
     }
@@ -61,7 +61,7 @@
     /**
      * Special cases from {@link Math#pow} and __ieee754_pow (in sharedRuntimeTrans.cpp).
      */
-    @MethodSubstitution
+    @MethodSubstitution(guard = UnsafeSubstitutions.GetAndSetGuard.class)
     public static double pow(double x, double y) {
         // If the second argument is positive or negative zero, then the result is 1.0.
         if (y == 0) {
@@ -107,7 +107,7 @@
     // accurate within [-pi/4, pi/4]. Examine the passed value and provide
     // a slow path for inputs outside of that interval.
 
-    @MethodSubstitution
+    @MethodSubstitution(guard = UnsafeSubstitutions.GetAndSetGuard.class)
     public static double sin(double x) {
         if (abs(x) < PI_4) {
             return MathIntrinsicNode.compute(x, Operation.SIN);
@@ -116,7 +116,7 @@
         }
     }
 
-    @MethodSubstitution
+    @MethodSubstitution(guard = UnsafeSubstitutions.GetAndSetGuard.class)
     public static double cos(double x) {
         if (abs(x) < PI_4) {
             return MathIntrinsicNode.compute(x, Operation.COS);
@@ -125,7 +125,7 @@
         }
     }
 
-    @MethodSubstitution
+    @MethodSubstitution(guard = UnsafeSubstitutions.GetAndSetGuard.class)
     public static double tan(double x) {
         if (abs(x) < PI_4) {
             return MathIntrinsicNode.compute(x, Operation.TAN);