assembler.hpp revision 665
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or // This file contains platform-independent assembler declarations. * Labels represent destinations for control transfer instructions. Such * instructions can accept a Label as their target argument. A Label is * bound to the current location in the code stream by calling the * MacroAssembler's 'bind' method, which in turn calls the Label's 'bind' * method. A Label may be referenced by an instruction before it's bound * (i.e., 'forward referenced'). 'bind' stores the current code offset * If an instruction references a bound Label, the offset field(s) within * the instruction are immediately filled in based on the Label's code * offset. If an instruction references an unbound label, that * instruction is put on a list of instructions that must be patched * (i.e., 'resolved') when the Label is bound. * 'bind' will call the platform-specific 'patch_instruction' method to * fill in the offset field(s) for each unresolved instruction (if there * are any). 'patch_instruction' lives in one of the * Instead of using a linked list of unresolved instructions, a Label has * an array of unresolved instruction code offsets. _patch_index * contains the total number of forward references. If the Label's array * overflows (i.e., _patch_index grows larger than the array size), a * GrowableArray is allocated to hold the remaining offsets. (The cache * size is 4 for now, which handles over 99.5% of the cases) * Labels may only be used within a single CodeSection. If you need * to create references between code sections, use explicit relocations. // _loc encodes both the binding state (via its sign) // and the binding locator (via its value) of a label. // _loc >= 0 bound label, loc() encodes the target (jump) position // _loc == -1 unbound label // References to instructions that jump to this unresolved label. // These instructions need to be patched when the label is bound // using the platform-specific patchInstruction() method. // To avoid having to allocate from the C-heap each time, we provide // a local cache and use the overflow only if we exceed the local cache * After binding, be sure 'patch_instructions' is called later to link // Iterates over all unresolved instructions for printing * Returns the position of the the Label in the code buffer * The position is a 'locator', which encodes both offset and section. int loc_pos()
const;
// == locator_pos(loc()) int loc_sect()
const;
// == locator_sect(loc()) * Adds a reference to an unresolved displacement instruction to * @param cb the code buffer being patched * @param branch_loc the locator of the branch instruction in the code buffer * Iterate over the list of patches, resolving the instructions * Call patch_instruction on each 'branch_loc' value // A union type for code which has to assemble both constant and // non-constant operands, when the distinction cannot be made // The Abstract Assembler: Pure assembler doing NO optimizations on the // instruction level; i.e., what you write is what you get. // The Assembler is generating code into a CodeBuffer. // Code emission & accessing // This routine is called with a label is used for an address. // Labels and displacements truck in offsets, but target must return a PC. bool is8bit(
int x)
const {
return -
0x80 <= x && x <
0x80; }
bool isByte(
int x)
const {
return 0 <= x && x <
0x100; }
void emit_word(
int x);
// emit a 16-bit word (not a wordSize word!) void emit_long(
jint x);
// emit a 32-bit word (not a longSize word!) // Instruction boundaries (required when emitting relocatable values). // Make it return true on platforms which need to verify // instruction boundaries for some operations. // save end pointer back to code buf. // ensure buf contains all code (call this before using/copying the code) int sect()
const;
// return _code_section->index() int locator()
const;
// CodeBuffer::locator(offset(), sect()) static int code_fill_byte();
// used to pad out odd-sized code buffers // Associate a comment with the current offset. It will be printed // along with the disassembly when printing nmethods. Currently // only supported in the instruction section of the code buffer. void bind(
Label& L);
// binds an unbound label L to the current code position // Move to a different section in the same code buffer. // Inform assembler when generating stub code and relocation info // Bootstrapping aid to cope with delayed determination of constants. // Returns a static address which will eventually contain the constant. // The value zero (NULL) stands instead of a constant which is still uncomputed. // Thus, the eventual value of the constant must not be zero. // This is fine, since this is designed for embedding object field // offsets in code which must be generated before the object class is loaded. // Field offsets are never zero, since an object's header (mark word) // is located at offset zero. // Last overloading is platform-dependent; look in assembler_<arch>.cpp. // Bang stack to trigger StackOverflowError at a safe location // implementation delegates to machine-specific bang_stack_with_offset * A platform-dependent method to patch a jump instruction that refers * @param branch the location of the instruction to patch * @param masm the assembler which generated the branch * Platform-dependent method of printing an instruction that needs to be * @param branch the instruction to be patched in the buffer.