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 } 40 41 @Opcode private final IntrinsicOpcode opcode; 42 @Def protected AllocatableValue result; 43 @Use({OperandFlag.REG, OperandFlag.STACK}) protected AllocatableValue input; 44 45 public AMD64BitManipulationOp(IntrinsicOpcode opcode, AllocatableValue result, AllocatableValue input) { 46 this.opcode = opcode; 47 this.result = result; 48 this.input = input; 49 } 50 51 @Override 52 public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { 53 Register dst = ValueUtil.asIntReg(result); 54 if (ValueUtil.isRegister(input)) { 55 Register src = ValueUtil.asRegister(input); 56 switch (opcode) { 57 case IPOPCNT: 58 masm.popcntl(dst, src); 59 break; 60 case LPOPCNT: 61 masm.popcntq(dst, src); 62 break; 63 case BSF: 64 masm.bsfq(dst, src); 65 break; 66 case IBSR: 67 masm.bsrl(dst, src); 68 break; 69 case LBSR: 70 masm.bsrq(dst, src); 71 break; 72 } 73 } else { 74 AMD64Address src = (AMD64Address) crb.asAddress(input); 75 switch (opcode) { 76 case IPOPCNT: 77 masm.popcntl(dst, src); 78 break; 79 case LPOPCNT: 80 masm.popcntq(dst, src); 81 break; 82 case BSF: 83 masm.bsfq(dst, src); 84 break; 85 case IBSR: 86 masm.bsrl(dst, src); 87 break; 88 case LBSR: 89 masm.bsrq(dst, src); 90 break; 91 } 92 } 93 } 94 95 }