1 /* 2 * Copyright (c) 2012, 2012, 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 */ 23 package com.oracle.graal.lir.amd64; 24 25 import com.oracle.graal.api.code.*; 26 import com.oracle.graal.api.meta.*; 27 import com.oracle.graal.asm.amd64.*; 28 import com.oracle.graal.lir.*; 29 import com.oracle.graal.lir.asm.*; 30 31 public class AMD64BitManipulationOp extends AMD64LIRInstruction { 32 33 public enum IntrinsicOpcode { 34 IPOPCNT, 35 LPOPCNT, 36 IBSR, 37 LBSR, 38 BSF, 39 ILZCNT, 40 LLZCNT, 41 ITZCNT, 42 LTZCNT 43 } 44 45 @Opcode private final IntrinsicOpcode opcode; 46 @Def protected AllocatableValue result; 47 @Use({OperandFlag.REG, OperandFlag.STACK}) protected AllocatableValue input; 48 49 public AMD64BitManipulationOp(IntrinsicOpcode opcode, AllocatableValue result, AllocatableValue input) { 50 this.opcode = opcode; 51 this.result = result; 52 this.input = input; 53 } 54 55 @Override 56 public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { 57 Register dst = ValueUtil.asIntReg(result); 58 if (ValueUtil.isRegister(input)) { 59 Register src = ValueUtil.asRegister(input); 60 switch (opcode) { 61 case IPOPCNT: 62 masm.popcntl(dst, src); 63 break; 64 case LPOPCNT: 65 masm.popcntq(dst, src); 66 break; 67 case BSF: 68 masm.bsfq(dst, src); 69 break; 70 case IBSR: 71 masm.bsrl(dst, src); 72 break; 73 case LBSR: 74 masm.bsrq(dst, src); 75 break; 76 case ILZCNT: 77 masm.lzcntl(dst, src); 78 break; 79 case LLZCNT: 80 masm.lzcntq(dst, src); 81 break; 82 case ITZCNT: 83 masm.tzcntl(dst, src); 84 break; 85 case LTZCNT: 86 masm.tzcntq(dst, src); 87 break; 88 } 89 } else { 90 AMD64Address src = (AMD64Address) crb.asAddress(input); 91 switch (opcode) { 92 case IPOPCNT: 93 masm.popcntl(dst, src); 94 break; 95 case LPOPCNT: 96 masm.popcntq(dst, src); 97 break; 98 case BSF: 99 masm.bsfq(dst, src); 100 break; 101 case IBSR: 102 masm.bsrl(dst, src); 103 break; 104 case LBSR: 105 masm.bsrq(dst, src); 106 break; 107 case ILZCNT: 108 masm.lzcntl(dst, src); 109 break; 110 case LLZCNT: 111 masm.lzcntq(dst, src); 112 break; 113 case ITZCNT: 114 masm.tzcntl(dst, src); 115 break; 116 case LTZCNT: 117 masm.tzcntq(dst, src); 118 break; 119 } 120 } 121 } 122 123 }