diff graal/com.oracle.max.asmdis/src/com/sun/max/asm/Label.java @ 3733:e233f5660da4

Added Java files from Maxine project.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sat, 17 Dec 2011 19:59:18 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.asmdis/src/com/sun/max/asm/Label.java	Sat Dec 17 19:59:18 2011 +0100
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2007, 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.asm;
+
+import com.sun.max.program.*;
+
+/**
+ * Assembler labels for symbolic addressing.
+ *
+ * This class provides combined functionality for both 32-bit and 64-bit address spaces.
+ * The respective assembler narrows the usable interface to either.
+ *
+ * @see Assembler32
+ * @see Assembler64
+ */
+public final class Label implements Argument {
+
+    public enum State {
+        UNASSIGNED, BOUND, FIXED_32, FIXED_64;
+    }
+
+    protected State state = State.UNASSIGNED;
+
+    public static Label createBoundLabel(int position) {
+        final Label label = new Label();
+        label.bind(position);
+        return label;
+    }
+
+    public Label() {
+    }
+
+    public State state() {
+        return state;
+    }
+
+    private int position;
+
+    /**
+     * Must only be called when the label is bound!
+     */
+    public int position() throws AssemblyException {
+        if (state != State.BOUND) {
+            throw new AssemblyException("unassigned or unbound label");
+        }
+        return position;
+    }
+
+    /**
+     * Binds this label to a position in the assembler's instruction stream that represents the start of an instruction.
+     * The assembler may update the position if any emitted instructions change lengths, so that this label keeps
+     * denoting the same logical instruction.
+     *
+     * Only to be called by {@link Assembler#bindLabel(Label)}.
+     *
+     * @param pos
+     *            an instruction's position in the assembler's instruction stream
+     *
+     * @see Assembler#bindLabel(Label)
+     */
+    void bind(int pos) {
+        this.position = pos;
+        state = State.BOUND;
+    }
+
+    void adjust(int delta) {
+        assert state == State.BOUND;
+        position += delta;
+    }
+
+    private int address32;
+    private long address64;
+
+    /**
+     * Assigns a fixed, absolute 32-bit address to this label.
+     * If used in a 64-bit assembler,
+     * the effective address value would be unsigned-extended.
+     *
+     * @param address an absolute memory location
+     *
+     * @see Assembler#bindLabel(Label)
+     */
+    void fix32(int addr32) {
+        this.address32 = addr32;
+        state = State.FIXED_32;
+    }
+
+    /**
+     * Assigns a fixed, absolute 64-bit address to this label.
+     *
+     * @param address an absolute memory location
+     *
+     * @see Assembler#bindLabel(Label)
+     */
+    void fix64(long addr64) {
+        this.address64 = addr64;
+        state = State.FIXED_64;
+    }
+
+    /**
+     * Must only be called if this label has been {@link #fix32 fixed}.
+     */
+    public int address32() throws AssemblyException {
+        switch (state) {
+            case FIXED_32: {
+                return address32;
+            }
+            case FIXED_64: {
+                throw ProgramError.unexpected("64-bit address in 32-bit assembler");
+            }
+            default: {
+                throw new AssemblyException("unassigned or unfixed label");
+            }
+        }
+    }
+
+    /**
+     * Must only be called if this label has been {@link #fix64 fixed}.
+     */
+    public long address64() throws AssemblyException {
+        switch (state) {
+            case FIXED_64: {
+                return address64;
+            }
+            case FIXED_32: {
+                throw ProgramError.unexpected("32-bit address in 64-bit assembler");
+            }
+            default: {
+                throw new AssemblyException("unassigned or unfixed label");
+            }
+        }
+    }
+
+    public String externalValue() {
+        throw ProgramError.unexpected();
+    }
+
+    public String disassembledValue() {
+        throw ProgramError.unexpected();
+    }
+
+    public long asLong() {
+        throw ProgramError.unexpected("unimplemented");
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (other instanceof Label) {
+            final Label label = (Label) other;
+            if (state != label.state) {
+                return false;
+            }
+            switch (state) {
+                case UNASSIGNED:
+                    return this == label;
+                case BOUND:
+                    return position == label.position;
+                case FIXED_32:
+                    return address32 == label.address32;
+                case FIXED_64:
+                    return address64 == label.address64;
+                default:
+                    throw ProgramError.unexpected();
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        switch (state) {
+            case BOUND:
+                return position;
+            case FIXED_32:
+                return address32;
+            case FIXED_64:
+                return (int) (address64 ^ (address64 >> 32));
+            default:
+                return super.hashCode();
+        }
+    }
+
+    @Override
+    public String toString() {
+        switch (state) {
+            case UNASSIGNED:
+                return "<unassigned>";
+            case BOUND:
+                return position >= 0 ? "+" + position : String.valueOf(position);
+            case FIXED_32:
+                return String.valueOf(address32);
+            case FIXED_64:
+                return String.valueOf(address64);
+            default:
+                throw ProgramError.unexpected();
+        }
+    }
+}