001/* 002 * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.asm.amd64.test; 024 025import com.oracle.graal.asm.amd64.*; 026import com.oracle.graal.asm.test.*; 027 028import static jdk.internal.jvmci.code.ValueUtil.*; 029import static jdk.internal.jvmci.common.UnsafeAccess.*; 030import static org.junit.Assume.*; 031 032import java.lang.reflect.*; 033 034import jdk.internal.jvmci.amd64.*; 035import jdk.internal.jvmci.code.*; 036import jdk.internal.jvmci.meta.*; 037 038import org.junit.*; 039 040public class IncrementDecrementMacroTest extends AssemblerTest { 041 042 @Before 043 public void checkAMD64() { 044 assumeTrue("skipping AMD64 specific test", codeCache.getTarget().arch instanceof AMD64); 045 } 046 047 public static class LongField { 048 public long x; 049 050 LongField(long x) { 051 this.x = x; 052 } 053 } 054 055 private static class IncrementCodeGenTest implements CodeGenTest { 056 final int value; 057 058 public IncrementCodeGenTest(int value) { 059 this.value = value; 060 } 061 062 @Override 063 public byte[] generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc) { 064 AMD64MacroAssembler asm = new AMD64MacroAssembler(target, registerConfig); 065 Register ret = registerConfig.getReturnRegister(Kind.Int); 066 try { 067 Field f = LongField.class.getDeclaredField("x"); 068 AMD64Address arg = new AMD64Address(asRegister(cc.getArgument(0)), (int) unsafe.objectFieldOffset(f)); 069 asm.incrementq(arg, value); 070 asm.movq(ret, arg); 071 asm.ret(0); 072 return asm.close(true); 073 } catch (Exception e) { 074 throw new RuntimeException("exception while trying to generate field access:", e); 075 } 076 } 077 } 078 079 private void assertIncrement(long initValue, int increment) { 080 assertReturn("longFieldStubIncrement", new IncrementCodeGenTest(increment), initValue + increment, new LongField(initValue)); 081 } 082 083 private void assertIncrements(int increment) { 084 assertIncrement(0x4242_4242_4242_4242L, increment); 085 } 086 087 @SuppressWarnings("unused") 088 public static long longFieldStubIncrement(LongField arg) { 089 return 0; 090 } 091 092 private static class DecrementCodeGenTest implements CodeGenTest { 093 final int value; 094 095 public DecrementCodeGenTest(int value) { 096 this.value = value; 097 } 098 099 @Override 100 public byte[] generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc) { 101 AMD64MacroAssembler asm = new AMD64MacroAssembler(target, registerConfig); 102 Register ret = registerConfig.getReturnRegister(Kind.Int); 103 try { 104 Field f = LongField.class.getDeclaredField("x"); 105 AMD64Address arg = new AMD64Address(asRegister(cc.getArgument(0)), (int) unsafe.objectFieldOffset(f)); 106 asm.decrementq(arg, value); 107 asm.movq(ret, arg); 108 asm.ret(0); 109 return asm.close(true); 110 } catch (Exception e) { 111 throw new RuntimeException("exception while trying to generate field access:", e); 112 } 113 } 114 } 115 116 private void assertDecrement(long initValue, int increment) { 117 assertReturn("longFieldStubDecrement", new DecrementCodeGenTest(increment), initValue - increment, new LongField(initValue)); 118 } 119 120 private void assertDecrements(int increment) { 121 assertDecrement(0x4242_4242_4242_4242L, increment); 122 } 123 124 @SuppressWarnings("unused") 125 public static long longFieldStubDecrement(LongField arg) { 126 return 0; 127 } 128 129 @Test 130 public void incrementMemTest0() { 131 int increment = 0; 132 assertIncrements(increment); 133 } 134 135 @Test 136 public void incrementMemTest1() { 137 int increment = 1; 138 assertIncrements(increment); 139 } 140 141 @Test 142 public void incrementMemTest2() { 143 int increment = 2; 144 assertIncrements(increment); 145 } 146 147 @Test 148 public void incrementMemTest3() { 149 int increment = Integer.MAX_VALUE; 150 assertIncrements(increment); 151 } 152 153 @Test 154 public void incrementMemTest4() { 155 int increment = Integer.MIN_VALUE; 156 assertIncrements(increment); 157 } 158 159 @Test 160 public void incrementMemTest5() { 161 int increment = -1; 162 assertIncrements(increment); 163 } 164 165 @Test 166 public void incrementMemTest6() { 167 int increment = -2; 168 assertIncrements(increment); 169 } 170 171 @Test 172 public void incrementMemTest7() { 173 int increment = -0x1000_0000; 174 assertIncrements(increment); 175 } 176 177 @Test 178 public void decrementMemTest0() { 179 int decrement = 0; 180 assertDecrements(decrement); 181 } 182 183 @Test 184 public void decrementMemTest1() { 185 int decrement = 1; 186 assertDecrements(decrement); 187 } 188 189 @Test 190 public void decrementMemTest2() { 191 int decrement = 2; 192 assertDecrements(decrement); 193 } 194 195 @Test 196 public void decrementMemTest3() { 197 int decrement = Integer.MAX_VALUE; 198 assertDecrements(decrement); 199 } 200 201 @Test 202 public void decrementMemTest4() { 203 int decrement = Integer.MIN_VALUE; 204 assertDecrements(decrement); 205 } 206 207 @Test 208 public void decrementMemTest5() { 209 int decrement = -1; 210 assertDecrements(decrement); 211 } 212 213 @Test 214 public void decrementMemTest6() { 215 int decrement = -2; 216 assertDecrements(decrement); 217 } 218 219 @Test 220 public void decrementMemTest7() { 221 int decrement = -0x1000_0000; 222 assertDecrements(decrement); 223 } 224 225}