view graal/com.oracle.max.asmdis/src/com/sun/max/asm/gen/risc/RiscTemplate.java @ 4142:bc8527f3071c

Adjust code base to new level of warnings.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sun, 18 Dec 2011 05:24:06 +0100
parents e233f5660da4
children
line wrap: on
line source

/*
 * 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.gen.risc;

import java.util.*;

import com.sun.max.asm.gen.*;
import com.sun.max.asm.gen.risc.field.*;
import com.sun.max.program.*;

/**
 */
public class RiscTemplate extends Template implements RiscInstructionDescriptionVisitor {

    private final List<RiscField> allFields = new LinkedList<>();
    private final List<OperandField> operandFields = new LinkedList<>();
    private final List<OptionField> optionFields = new LinkedList<>();
    private final List<OperandField> parameters = new ArrayList<>();
    private final List<Option> options = new LinkedList<>();

    private int opcode;
    private int opcodeMask;
    private RiscTemplate canonicalRepresentative;

    public RiscTemplate(InstructionDescription instructionDescription) {
        super(instructionDescription);
    }

    @Override
    public RiscInstructionDescription instructionDescription() {
        return (RiscInstructionDescription) super.instructionDescription();
    }

    private RiscTemplate synthesizedFrom;

    public void setSynthesizedFrom(RiscTemplate synthesizedFrom) {
        assert instructionDescription().isSynthetic();
        this.synthesizedFrom = synthesizedFrom;
    }

    public RiscTemplate synthesizedFrom() {
        return synthesizedFrom;
    }

    /**
     * Adds the value of a constant field to the opcode of the instruction and
     * updates the opcode mask to include the bits of the field.
     *
     * @param field a field containing a constant value
     * @param value the constant value
     */
    private void organizeConstant(RiscField field, int value) {
        try {
            opcode |= field.bitRange().assembleUnsignedInt(value);
            opcodeMask |= field.bitRange().instructionMask();
        } catch (IndexOutOfBoundsException indexOutOfBoundsException) {
            throw ProgramError.unexpected("operand for constant field " + field.name() + " does not fit: " + value);
        }
    }

    public void visitField(RiscField field) {
        allFields.add(field);
        if (field instanceof OperandField) {
            final OperandField operandField = (OperandField) field;
            if (field instanceof OffsetParameter) {
                setLabelParameterIndex();
            }
            if (operandField.boundTo() == null) {
                parameters.add(operandField);
            }
            operandFields.add(operandField);
        } else if (field instanceof OptionField) {
            optionFields.add((OptionField) field);
        } else if (field instanceof ReservedField) {
            organizeConstant(field, 0);
        } else {
            throw ProgramError.unexpected("unknown or unallowed type of field: " + field);
        }
    }

    public void visitConstant(RiscConstant constant) {
        organizeConstant(constant.field(), constant.value());
    }

    public void visitConstraint(InstructionConstraint constraint) {
    }

    /**
     * Sets the internal name of this template from a given string it is not already set.
     *
     * @param string  a string specified in the to consider
     */
    public void visitString(String string) {
        if (internalName() == null) {
            setInternalName(string);
        }
    }

    public List<OperandField> operandFields() {
        return operandFields;
    }

    public int opcode() {
        return opcode;
    }

    public int opcodeMask() {
        return opcodeMask;
    }

    public List<OptionField> optionFields() {
        return optionFields;
    }

    public void addOptionField(OptionField f) {
        allFields.add(f);
        optionFields.add(f);
    }

    public int specificity() {
        return Integer.bitCount(opcodeMask);
    }

    public void organizeOption(Option option, RiscTemplate newCanonicalRepresentative) {
        instructionDescription().setExternalName(externalName() + option.externalName());
        setInternalName(internalName() + option.name());
        try {
            opcode |= option.field().bitRange().assembleUnsignedInt(option.value());
            opcodeMask |= option.field().bitRange().instructionMask();
        } catch (IndexOutOfBoundsException e) {
            throw ProgramError.unexpected("Option: " + option.name() + " does not fit in field " + option.field().name());
        }

        options.add(option);
        if (option.isRedundant()) {
            this.canonicalRepresentative = newCanonicalRepresentative;
        }
    }

    @Override
    public Template canonicalRepresentative() {
        return canonicalRepresentative;
    }

    @Override
    public String assemblerMethodName() {
        return internalName();
    }

    @Override
    public List<Operand> operands() {
        throw ProgramError.unexpected("unimplemented");
    }

    @Override
    public List<OperandField> parameters() {
        return parameters;
    }

    @Override
    public String toString() {
        return "<" + getClass().getSimpleName() + " #" + serial() + ": " + internalName() + " " + Integer.toHexString(opcode()) + ", " + parameters() + ">";
    }

}