Commit 7cf96ad6 authored by Andreas Fried's avatar Andreas Fried
Browse files

amd64: Add instructions bsf and bsr.

parent f2eb5e7f
......@@ -334,6 +334,20 @@ static void amd64_emit_am(const ir_node *const node, bool indirect_star)
emit_register_mode(reg, binop_attr->base.insn_mode);
return;
}
case AMD64_OP_OUTREG_ADDR: {
amd64_emit_addr(node, &attr->addr);
be_emit_cstring(", ");
goto emit_reg_out0;
}
case AMD64_OP_OUTREG_REG: {
const arch_register_t *reg_in = arch_get_irn_register_in(node, 0);
emit_register_mode(reg_in, attr->insn_mode);
be_emit_cstring(", ");
emit_reg_out0:;
const arch_register_t *reg_out = arch_get_irn_register_out(node, 0);
emit_register_mode(reg_out, attr->insn_mode);
return;
}
case AMD64_OP_ADDR_IMM: {
const amd64_binop_addr_attr_t *const binop_attr
= (const amd64_binop_addr_attr_t*)attr;
......
......@@ -32,18 +32,20 @@
static const char *get_op_mode_string(amd64_op_mode_t mode)
{
switch (mode) {
case AMD64_OP_ADDR_IMM: return "addr+imm";
case AMD64_OP_ADDR_REG: return "addr+reg";
case AMD64_OP_ADDR: return "addr";
case AMD64_OP_IMM32: return "imm32";
case AMD64_OP_IMM64: return "imm64";
case AMD64_OP_NONE: return "none";
case AMD64_OP_REG_ADDR: return "reg+addr";
case AMD64_OP_REG_IMM: return "reg+imm";
case AMD64_OP_REG_REG: return "reg+reg";
case AMD64_OP_REG: return "reg";
case AMD64_OP_SHIFT_IMM: return "shift_imm";
case AMD64_OP_SHIFT_REG: return "shift_reg";
case AMD64_OP_ADDR_IMM: return "addr+imm";
case AMD64_OP_ADDR_REG: return "addr+reg";
case AMD64_OP_ADDR: return "addr";
case AMD64_OP_IMM32: return "imm32";
case AMD64_OP_IMM64: return "imm64";
case AMD64_OP_NONE: return "none";
case AMD64_OP_REG_ADDR: return "reg+addr";
case AMD64_OP_REG_IMM: return "reg+imm";
case AMD64_OP_REG_REG: return "reg+reg";
case AMD64_OP_OUTREG_REG: return "outreg+reg";
case AMD64_OP_OUTREG_ADDR: return "outreg+addr";
case AMD64_OP_REG: return "reg";
case AMD64_OP_SHIFT_IMM: return "shift_imm";
case AMD64_OP_SHIFT_REG: return "shift_reg";
}
panic("invalid op_mode");
}
......
......@@ -41,6 +41,8 @@ static inline bool amd64_has_addr_attr(const ir_node *node)
return amd64_has_binop_attr(node)
|| attr->op_mode == AMD64_OP_ADDR
|| attr->op_mode == AMD64_OP_REG
|| attr->op_mode == AMD64_OP_OUTREG_REG
|| attr->op_mode == AMD64_OP_OUTREG_ADDR
|| attr->op_mode == AMD64_OP_IMM32;
}
......
......@@ -47,6 +47,8 @@ typedef enum {
AMD64_OP_REG_ADDR,
AMD64_OP_REG_REG,
AMD64_OP_REG_IMM,
AMD64_OP_OUTREG_REG,
AMD64_OP_OUTREG_ADDR,
AMD64_OP_IMM32,
AMD64_OP_IMM64,
AMD64_OP_ADDR_REG,
......
......@@ -147,6 +147,16 @@ my $unop = {
."amd64_addr_t addr = { { NULL, 0, X86_IMM_VALUE }, NO_INPUT, NO_INPUT, NO_INPUT, 0, AMD64_SEGMENT_DEFAULT };",
};
my $unop_out = {
irn_flags => [ "modify_flags", "rematerializable" ],
in_reqs => [ "gp" ],
out_reqs => [ "gp", "flags" ],
ins => [ "val" ],
outs => [ "res", "flags" ],
attr_type => "amd64_addr_attr_t",
attr => "amd64_insn_mode_t insn_mode, amd64_op_mode_t op_mode, amd64_addr_t addr",
};
my $binopx = {
irn_flags => [ "rematerializable" ],
state => "exc_pinned",
......@@ -476,6 +486,16 @@ ret => {
emit => "ret",
},
bsf => {
template => $unop_out,
emit => "bsf%M %AM",
},
bsr => {
template => $unop_out,
emit => "bsr%M %AM",
},
# SSE
adds => {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment