< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ControlFlow.java

Print this page


   1 /*
   2  * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */


 266                 masm.cmpl(idxScratchReg, highKey - lowKey);
 267             } else {
 268                 masm.cmpl(idxScratchReg, highKey);
 269             }
 270 
 271             // Jump to default target if index is not within the jump table
 272             if (defaultTarget != null) {
 273                 masm.jcc(ConditionFlag.Above, defaultTarget.label());
 274             }
 275 
 276             // Set scratch to address of jump table
 277             masm.leaq(scratchReg, new AMD64Address(AMD64.rip, 0));
 278             final int afterLea = masm.position();
 279 
 280             // Load jump table entry into scratch and jump to it
 281             masm.movslq(idxScratchReg, new AMD64Address(scratchReg, idxScratchReg, Scale.Times4, 0));
 282             masm.addq(scratchReg, idxScratchReg);
 283             masm.jmp(scratchReg);
 284 
 285             // Inserting padding so that jump table address is 4-byte aligned
 286             if ((masm.position() & 0x3) != 0) {
 287                 masm.nop(4 - (masm.position() & 0x3));
 288             }
 289 
 290             // Patch LEA instruction above now that we know the position of the jump table
 291             // TODO this is ugly and should be done differently
 292             final int jumpTablePos = masm.position();
 293             final int leaDisplacementPosition = afterLea - 4;
 294             masm.emitInt(jumpTablePos - afterLea, leaDisplacementPosition);
 295 
 296             // Emit jump table entries
 297             for (LabelRef target : targets) {
 298                 Label label = target.label();
 299                 int offsetToJumpTableBase = masm.position() - jumpTablePos;
 300                 if (label.isBound()) {
 301                     int imm32 = label.position() - jumpTablePos;
 302                     masm.emitInt(imm32);
 303                 } else {
 304                     label.addPatchAt(masm.position());
 305 
 306                     masm.emitByte(0); // pseudo-opcode for jump table entry
 307                     masm.emitShort(offsetToJumpTableBase);
 308                     masm.emitByte(0); // padding to make jump table entry 4 bytes wide
 309                 }
 310             }
 311 
 312             JumpTable jt = new JumpTable(jumpTablePos, lowKey, highKey, 4);





























































































 313             crb.compilationResult.addAnnotation(jt);
 314         }
 315     }
 316 
 317     @Opcode("SETcc")
 318     public static final class CondSetOp extends AMD64LIRInstruction {
 319         public static final LIRInstructionClass<CondSetOp> TYPE = LIRInstructionClass.create(CondSetOp.class);
 320         @Def({REG, HINT}) protected Value result;
 321         private final ConditionFlag condition;
 322 
 323         public CondSetOp(Variable result, Condition condition) {
 324             super(TYPE);
 325             this.result = result;
 326             this.condition = intCond(condition);
 327         }
 328 
 329         @Override
 330         public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
 331             setcc(masm, result, condition);
 332         }


   1 /*
   2  * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */


 266                 masm.cmpl(idxScratchReg, highKey - lowKey);
 267             } else {
 268                 masm.cmpl(idxScratchReg, highKey);
 269             }
 270 
 271             // Jump to default target if index is not within the jump table
 272             if (defaultTarget != null) {
 273                 masm.jcc(ConditionFlag.Above, defaultTarget.label());
 274             }
 275 
 276             // Set scratch to address of jump table
 277             masm.leaq(scratchReg, new AMD64Address(AMD64.rip, 0));
 278             final int afterLea = masm.position();
 279 
 280             // Load jump table entry into scratch and jump to it
 281             masm.movslq(idxScratchReg, new AMD64Address(scratchReg, idxScratchReg, Scale.Times4, 0));
 282             masm.addq(scratchReg, idxScratchReg);
 283             masm.jmp(scratchReg);
 284 
 285             // Inserting padding so that jump table address is 4-byte aligned
 286             masm.align(4);


 287 
 288             // Patch LEA instruction above now that we know the position of the jump table
 289             // this is ugly but there is no better way to do this given the assembler API
 290             final int jumpTablePos = masm.position();
 291             final int leaDisplacementPosition = afterLea - 4;
 292             masm.emitInt(jumpTablePos - afterLea, leaDisplacementPosition);
 293 
 294             // Emit jump table entries
 295             for (LabelRef target : targets) {
 296                 Label label = target.label();
 297                 int offsetToJumpTableBase = masm.position() - jumpTablePos;
 298                 if (label.isBound()) {
 299                     int imm32 = label.position() - jumpTablePos;
 300                     masm.emitInt(imm32);
 301                 } else {
 302                     label.addPatchAt(masm.position());
 303 
 304                     masm.emitByte(0); // pseudo-opcode for jump table entry
 305                     masm.emitShort(offsetToJumpTableBase);
 306                     masm.emitByte(0); // padding to make jump table entry 4 bytes wide
 307                 }
 308             }
 309 
 310             JumpTable jt = new JumpTable(jumpTablePos, lowKey, highKey, 4);
 311             crb.compilationResult.addAnnotation(jt);
 312         }
 313     }
 314 
 315     public static final class HashTableSwitchOp extends AMD64BlockEndOp {
 316         public static final LIRInstructionClass<HashTableSwitchOp> TYPE = LIRInstructionClass.create(HashTableSwitchOp.class);
 317         private final JavaConstant[] keys;
 318         private final LabelRef defaultTarget;
 319         private final LabelRef[] targets;
 320         @Alive protected Value value;
 321         @Alive protected Value hash;
 322         @Temp({REG}) protected Value entryScratch;
 323         @Temp({REG}) protected Value scratch;
 324 
 325         public HashTableSwitchOp(final JavaConstant[] keys, final LabelRef defaultTarget, LabelRef[] targets, Value value, Value hash, Variable scratch, Variable entryScratch) {
 326             super(TYPE);
 327             this.keys = keys;
 328             this.defaultTarget = defaultTarget;
 329             this.targets = targets;
 330             this.value = value;
 331             this.hash = hash;
 332             this.scratch = scratch;
 333             this.entryScratch = entryScratch;
 334         }
 335 
 336         @Override
 337         public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
 338             Register valueReg = asRegister(value, AMD64Kind.DWORD);
 339             Register indexReg = asRegister(hash, AMD64Kind.DWORD);
 340             Register scratchReg = asRegister(scratch, AMD64Kind.QWORD);
 341             Register entryScratchReg = asRegister(entryScratch, AMD64Kind.QWORD);
 342 
 343             // Set scratch to address of jump table
 344             masm.leaq(scratchReg, new AMD64Address(AMD64.rip, 0));
 345             final int afterLea = masm.position();
 346 
 347             // When the default target is set, the jump table contains entries with two DWORDS:
 348             // the original key before hashing and the label jump address
 349             if (defaultTarget != null) {
 350 
 351                 // Move the table entry (two DWORDs) into a QWORD
 352                 masm.movq(entryScratchReg, new AMD64Address(scratchReg, indexReg, Scale.Times8, 0));
 353 
 354                 // Jump to the default target if the first DWORD (original key) doesn't match the
 355                 // current key. Accounts for hash collisions with unknown keys
 356                 masm.cmpl(entryScratchReg, valueReg);
 357                 masm.jcc(ConditionFlag.NotEqual, defaultTarget.label());
 358 
 359                 // Shift to the second DWORD
 360                 masm.sarq(entryScratchReg, 32);
 361             } else {
 362 
 363                 // The jump table has a single DWORD with the label address if there's no
 364                 // default target
 365                 masm.movslq(entryScratchReg, new AMD64Address(scratchReg, indexReg, Scale.Times4, 0));
 366             }
 367             masm.addq(scratchReg, entryScratchReg);
 368             masm.jmp(scratchReg);
 369 
 370             // Inserting padding so that jump the table address is aligned
 371             if (defaultTarget != null) {
 372                 masm.align(8);
 373             } else {
 374                 masm.align(4);
 375             }
 376 
 377             // Patch LEA instruction above now that we know the position of the jump table
 378             // this is ugly but there is no better way to do this given the assembler API
 379             final int jumpTablePos = masm.position();
 380             final int leaDisplacementPosition = afterLea - 4;
 381             masm.emitInt(jumpTablePos - afterLea, leaDisplacementPosition);
 382 
 383             // Emit jump table entries
 384             for (int i = 0; i < targets.length; i++) {
 385 
 386                 Label label = targets[i].label();
 387 
 388                 if (defaultTarget != null) {
 389                     masm.emitInt(keys[i].asInt());
 390                 }
 391                 if (label.isBound()) {
 392                     int imm32 = label.position() - jumpTablePos;
 393                     masm.emitInt(imm32);
 394                 } else {
 395                     int offsetToJumpTableBase = masm.position() - jumpTablePos;
 396                     label.addPatchAt(masm.position());
 397                     masm.emitByte(0); // pseudo-opcode for jump table entry
 398                     masm.emitShort(offsetToJumpTableBase);
 399                     masm.emitByte(0); // padding to make jump table entry 4 bytes wide
 400                 }
 401             }
 402 
 403             JumpTable jt = new JumpTable(jumpTablePos, keys[0].asInt(), keys[keys.length - 1].asInt(), 4);
 404             crb.compilationResult.addAnnotation(jt);
 405         }
 406     }
 407 
 408     @Opcode("SETcc")
 409     public static final class CondSetOp extends AMD64LIRInstruction {
 410         public static final LIRInstructionClass<CondSetOp> TYPE = LIRInstructionClass.create(CondSetOp.class);
 411         @Def({REG, HINT}) protected Value result;
 412         private final ConditionFlag condition;
 413 
 414         public CondSetOp(Variable result, Condition condition) {
 415             super(TYPE);
 416             this.result = result;
 417             this.condition = intCond(condition);
 418         }
 419 
 420         @Override
 421         public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
 422             setcc(masm, result, condition);
 423         }


< prev index next >