001    /*
002     *  This file is part of the Jikes RVM project (http://jikesrvm.org).
003     *
004     *  This file is licensed to You under the Eclipse Public License (EPL);
005     *  You may not use this file except in compliance with the License. You
006     *  may obtain a copy of the License at
007     *
008     *      http://www.opensource.org/licenses/eclipse-1.0.php
009     *
010     *  See the COPYRIGHT.txt file distributed with this work for information
011     *  regarding copyright ownership.
012     */
013    package org.jikesrvm.ia32;
014    
015    import org.jikesrvm.ArchitectureSpecific;
016    import org.jikesrvm.VM;
017    import org.jikesrvm.MachineSpecific;
018    import org.jikesrvm.SizeConstants;
019    import org.jikesrvm.runtime.Magic;
020    import org.vmmagic.pragma.Interruptible;
021    import org.vmmagic.pragma.Uninterruptible;
022    import org.vmmagic.unboxed.Address;
023    import org.vmmagic.unboxed.Offset;
024    import org.vmmagic.unboxed.Word;
025    
026    /**
027     * Wrappers around IA32-specific code common to both 32 & 64 bit
028     */
029    public abstract class MachineSpecificIA extends MachineSpecific implements ArchConstants {
030    
031      /**
032       * A well-known memory location used to manipulate the FPU control word.
033       */
034      static int FPUControlWord;
035    
036      /**
037       * Wrappers around IA32-specific code (32-bit specific)
038       */
039      public static final class IA32 extends MachineSpecificIA {
040        public static final IA32 singleton = new IA32();
041      }
042    
043      /**
044       * Wrappers around EMT64-specific code (64-bit specific)
045       */
046      public static final class EM64T extends MachineSpecificIA {
047        public static final EM64T singleton = new EM64T();
048      }
049    
050      /*
051      * Generic (32/64 neutral) IA support
052      */
053    
054      /* common to all ISAs */
055    
056      @Override
057      @Interruptible
058      public final void baselineEmitLoadTIB(ArchitectureSpecific.Assembler asm, int dest, int object, Offset tibOffset) {
059        if (VM.BuildFor32Addr) {
060          asm.emitMOV_Reg_RegDisp(GPR.lookup(dest), GPR.lookup(object), tibOffset);
061        } else {
062          asm.emitMOV_Reg_RegDisp_Quad(GPR.lookup(dest), GPR.lookup(object), tibOffset);
063        }
064      }
065    
066      @Override
067      @Uninterruptible
068      public final void initializeStack(ArchitectureSpecific.Registers contextRegisters, Address ip, Address sp) {
069        Address fp;
070        sp = sp.minus(STACKFRAME_HEADER_SIZE);                   // last word of header
071        fp = sp.minus(SizeConstants.BYTES_IN_ADDRESS + STACKFRAME_BODY_OFFSET);
072        Magic.setCallerFramePointer(fp, STACKFRAME_SENTINEL_FP);
073        Magic.setCompiledMethodID(fp, INVISIBLE_METHOD_ID);
074    
075        sp = sp.minus(SizeConstants.BYTES_IN_ADDRESS);                                 // allow for one local
076        contextRegisters.gprs.set(ESP.value(), sp.toWord());
077        contextRegisters.fp = fp;
078        contextRegisters.ip = ip;
079      }
080    
081      /* unique to IA */
082    
083      @Uninterruptible
084      @Override
085      public final void adjustESP(ArchitectureSpecific.Registers registers, Offset delta, boolean traceAdjustments) {
086        Word old = registers.gprs.get(ESP.value());
087        registers.gprs.set(ESP.value(), old.plus(delta));
088        if (traceAdjustments) {
089          VM.sysWrite(" esp =");
090          VM.sysWrite(registers.gprs.get(ESP.value()));
091        }
092      }
093    }