/*
* Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.max.vm.intrinsics;
import com.sun.cri.bytecode.*;
import com.sun.max.unsafe.*;
import com.sun.max.vm.runtime.*;
/**
* Definition of ID strings for Maxine-specific intrinsics.
*/
public class MaxineIntrinsicIDs {
/**
* Prefix of ID strings defined in this class to make them unique.
*/
private static final String p = "com.oracle.max.vm.intrinsics:";
/**
* Unsafe cast of a value to a different Java type, without any code emitted for the cast.
* <p>
* The method definition must have one of the following forms:
* <pre>
* static U m(T value)
* U T.m()
* where the value is cast from T to U. In the case of a non-static method definition, the this-pointer is cast.
* T and U must have the same register kind, i.e., it cannot be used to cast between integer and floating point
* types, or between 32-bit and 64-bit values.
* </pre>
*/
public static final String UNSAFE_CAST = p + "UNSAFE_CAST";
/**
* Allocates a requested block of memory within the current activation frame.
* The allocated memory is reclaimed when the method returns.
*
* The allocation is for the lifetime of the method execution. That is, the compiler
* reserves the space in the compiled size of the frame. As such, a failure
* to allocate the requested space will result in a {@link StackOverflowError}
* when the method's prologue is executed.
*
* The value on the top of the stack is the size in bytes to allocate.
* The result is the address of the allocated block. <b>N.B.</b> The contents of the block are uninitialized.
* <p>
* The method definition must have the following form:
* <pre>
* static Pointer m(@INTRINSIC.Constant int size);
* size: The number of bytes to allocate on the stack.
* This parameter must be a compile-time constant and a multiple of {@link Word#size()}
* refs: Specifies if the values that will be in the stack region at all safepoints in the
* method are object values. This parameter must be a compile-time constant.
* </pre>
*/
public static final String ALLOCA = p + "ALLOCA";
/**
* If the CPU supports it, then this intrinsic issues an instruction that improves the performance of spin loops by
* providing a hint to the processor that the current thread is in a spin loop. The processor may use this to
* optimize power consumption while in the spin loop.
*
* If the CPU does not support such an instruction, then nothing is emitted for this intrinsic.
* <p>
* The method definition must have the following form:
* <pre>
* static void m()
* </pre>
*/
public static final String PAUSE = p + "PAUSE";
/**
* Inserts machine code to generate a breakpoint trap.
* <p>
* The method definition must have the following form:
* <pre>
* static void m()
* </pre>
*/
public static final String BREAKPOINT_TRAP = p + "BREAKPOINT_TRAP";
/**
* Returns the index of the least significant bit set in a given value.
* <p>
* The method definition must have the following form:
* <pre>
* static int m(Word value)
* value: the value to scan for the least significant bit
* returns: the index of the least significant bit within value, or -1 if value == 0
* </pre>
*/
public static final String LSB = p + "LSB";
/**
* Returns the index of the most significant bit set in a given value.
* <p>
* The method definition must have the following form:
* <pre>
* static int m(Word value)
* value: the value to scan for the least significant bit
* returns: the index of the most significant bit within value, or -1 if value == 0
* </pre>
*/
public static final String MSB = p + "MSB";
/**
* Reads the value of a register playing a runtime-defined role.
* <p>
* The method definition must have the following form:
* <pre>
* static Word m(@INTRINSIC.Constant int registerId);
* registerId: The {@link VMRegister register id} of the register to read.
* This parameter must be a compile-time constant.
* </pre>
*/
public static final String READREG = p + "READREG";
/**
* Writes the value of a register playing a runtime-defined role.
* <p>
* The method definition must have the following form:
* <pre>
* static void m(@INTRINSIC.Constant int registerId, Word value);
* registerId: The {@link VMRegister register id} of the register to write.
* This parameter must be a compile-time constant.
* value: The value to write into the register.
* </pre>
*/
public static final String WRITEREG = p + "WRITEREG";
/**
* Reads/tests the value of a bit specified by the {@link VMRegister#LATCH} register, a byte offset,
* and a bit number (LSB=0), that will be then used to branch on the value. I.e. this is not a general
* purpose bit reading mechanism.
* <p>
* The method definition must have the following form:
* <pre>
* static boolean m(@INTRINSIC.Constant int offset, @INTRINSIC.Constant int bit);
* offset: The offset of the address to read.
* bit: The bit of the memory cell to read.
* Both parameters must be compile-time constants.
* The call of the intrinsic must be followed by an {@link Bytecodes#IFEQ} or {@link Bytecodes#IFNE} bytecode.
* </pre>
*/
public static final String IFLATCHBITREAD = p + "IFLATCHBITREAD";
/**
* Reads a value from memory.
* <p>
* The method definition must have one of the following signatures:
* <pre>
* T (int offset)
* T (Offset offset)
*
* where T is any Java type (primitive type, Object, or Word)
*
* this: The base of the address to read.
* offset: The offset of the address to read.
* The accessed address is computed as 'base + offset'.
* </pre>
*/
public static final String PREAD_OFF = p + "PREAD_OFF";
/**
* Reads a value from memory.
* <p>
* The method definition must have the following signature:
* <pre>
* T (int displacement, int index)
*
* where T is any Java type (primitive type, Object, or Word)
*
* this: The base of the address to read.
* displacement, index: The displacement and index of the address to read
* The accessed address is computed as 'base + displacement + index * n', where n is the size of type T.
* </pre>
*/
public static final String PREAD_IDX = p + "PREAD_IDX";
/**
* Writes a value to memory.
* <p>
* The method definition must have one of the following signatures:
* <pre>
* void (int offset, T value)
* void (Offset offset, T value)
*
* where T is any Java type (primitive type, Object, or Word)
*
* this: The base of the address to write.
* offset: The offset of the address to write.
* The accessed address is computed as 'base + offset'.
* value: The value to write.
* </pre>
*/
public static final String PWRITE_OFF = p + "PWRITE_OFF";
/**
* Writes a value to memory.
* <p>
* The method definition must have one of the following forms:
* The method definition must have one of the following signatures:
* <pre>
*
* void (int offset, T value)
* void (Offset offset, T value)
* void (int displacement, int index, T value)
*
* where T is any Java type (primitive type, Object, or Word)
*
* this: The base of the address to write.
* displacement, index: The displacement and index of the address to write.
* The accessed address is computed as 'base + displacement + index * n', where n is the size of type T.
* value: The value to write.
* </pre>
*/
public static final String PWRITE_IDX = p + "PWRITE_IDX";
/**
* Atomic update of a value in memory.
*
* Compares {@code expectedValue} value with the actual value in a memory location (given by {@code pointer + offset}).
* Iff they are same, {@code newValue} is stored into the memory location and the {@code expectedValue} is returned.
* Otherwise, the actual value is returned.
* <p>
* The method definition must have one of the following forms:
* <pre>
* T Pointer.compareAndSwapInt(int offset, T expectedValue, T newValue)
* T Pointer.compareAndSwapInt(Offset offset, T expectedValue, T newValue)
* where T is one of {int, long, Object}
*
* this: The base of the address to read.
* offset: The offset of the address to read.
* expectedValue: if this value is currently in the memory location, perform the swap
* newValue: the new value to store into the memory location
* returns: either expectedValue or the actual value
* </pre>
*/
public static final String PCMPSWP = p + "PCMPSWP";
/**
* Record debug info at the current code location
* and emit the instruction(s) that enable a thread
* to be safely stopped for a VM operation (e.g. a GC).
* <p>
* The method definition must have the following form:
* <pre>
* static void m();
* </pre>
*/
public static final String SAFEPOINT_POLL = p + "INFOPOINT:SAFEPOINT_POLL";
/**
* Record debug info at the current code location
* and push its address to the stack. This is useful (for example)
* when initiating a stack walk from the current execution position.
* <p>
* The method definition must have the following form:
* <pre>
* static long m();
* </pre>
*/
public static final String HERE = p + "INFOPOINT:HERE";
/**
* Record debug info at the current code location.
* No instructions are emitted.
* <p>
* The method definition must have the following form:
* <pre>
* static void m();
* </pre>
*/
public static final String INFO = p + "INFOPOINT:INFO";
/**
* Record debug info at the current code location and deoptimize if it is executed.
* <p>
* The method definition must have the following form:
* <pre>
* static void m();
* </pre>
*/
public static final String UNCOMMON_TRAP = p + "INFOPOINT:UNCOMMON_TRAP";
/**
* Emulate one of the raw comparison bytecodes for long, float, or double. The returned value
* adheres to the Java bytecode specification of the given opcode.
* <p>
* The method definition must have the following form:
* <pre>
* static int m(@INTRINSIC.Constant int opcode, T l, T r);
* where T is one of {long, float, double}
*
* opcode: One of the following opcodes: {@link Bytecodes#LCMP}, {@link Bytecodes#FCMPL}, {@link Bytecodes#FCMPG}, {@link Bytecodes#DCMPL}, {@link Bytecodes#DCMPG}
* This parameter must be a compile-time constant.
* l, r: The values to compare. The type T must match the type of the opcode.
* </pre>
*/
public static final String CMP_BYTECODE = p + "CMP_BYTECODE";
}