Commit 0263ece7 authored by Christoph Mallon's avatar Christoph Mallon
Browse files

amd64, ia32: Support the asm modifier 'c'.

parent df7b9be1
......@@ -7,6 +7,7 @@ libFirm 1.22.1 (2016-01-07)
* Generate 'mov $~0x80000000, %r; ror x, %r' for '~(0x80000000 >> x)' (ia32)
* Stub support for the asm constraint modifier '%'
* Support the asm constraint 'e' (amd64, ia32)
* Support the asm modifier 'c' (amd64, ia32)
* Bugfixes
libFirm 1.22.0 (2015-12-31)
......
......@@ -698,6 +698,7 @@ static void emit_amd64_asm_register(const arch_register_t *reg, char modifier,
static void emit_amd64_asm_operand(ir_node const *const node, char const modifier, unsigned const pos)
{
x86_asm_operand_kind_t required;
switch (modifier) {
case '\0':
case 'b':
......@@ -705,6 +706,11 @@ static void emit_amd64_asm_operand(ir_node const *const node, char const modifie
case 'k':
case 'q':
case 'w':
required = ASM_OP_INVALID;
break;
case 'c':
required = ASM_OP_IMMEDIATE;
break;
default:
......@@ -714,6 +720,13 @@ static void emit_amd64_asm_operand(ir_node const *const node, char const modifie
be_asm_attr_t const *const attr = get_be_asm_attr_const(node);
x86_asm_operand_t const *const op = &((x86_asm_operand_t const*)attr->operands)[pos];
if (required != ASM_OP_INVALID && required != op->kind) {
char const *const name = x86_get_constraint_name(required);
be_errorf(node, "asm modifier '%c' requires an operand of type '%s'", modifier, name);
return;
}
switch ((x86_asm_operand_kind_t)op->kind) {
case ASM_OP_INVALID:
panic("invalid asm operand");
......@@ -737,7 +750,7 @@ static void emit_amd64_asm_operand(ir_node const *const node, char const modifie
}
case ASM_OP_IMMEDIATE: {
amd64_emit_immediate32(true, &op->u.imm32);
amd64_emit_immediate32(modifier != 'c', &op->u.imm32);
return;
}
}
......
......@@ -952,12 +952,18 @@ static void emit_ia32_asm_register(const arch_register_t *reg, char modifier,
static void emit_ia32_asm_operand(ir_node const *const node, char const modifier, unsigned const pos)
{
x86_asm_operand_kind_t required;
switch (modifier) {
case '\0':
case 'b':
case 'h':
case 'k':
case 'w':
required = ASM_OP_INVALID;
break;
case 'c':
required = ASM_OP_IMMEDIATE;
break;
default:
......@@ -967,6 +973,13 @@ static void emit_ia32_asm_operand(ir_node const *const node, char const modifier
be_asm_attr_t const *const attr = get_be_asm_attr_const(node);
x86_asm_operand_t const *const op = &((x86_asm_operand_t const*)attr->operands)[pos];
if (required != ASM_OP_INVALID && required != op->kind) {
char const *const name = x86_get_constraint_name(required);
be_errorf(node, "asm modifier '%c' requires an operand of type '%s'", modifier, name);
return;
}
switch ((x86_asm_operand_kind_t)op->kind) {
case ASM_OP_INVALID:
panic("invalid asm operand");
......@@ -990,7 +1003,7 @@ static void emit_ia32_asm_operand(ir_node const *const node, char const modifier
}
case ASM_OP_IMMEDIATE:
emit_ia32_immediate(true, &op->u.imm32);
emit_ia32_immediate(modifier != 'c', &op->u.imm32);
return;
}
panic("invalid asm operand kind");
......
......@@ -231,3 +231,15 @@ fine:
be_set_constraint_support(ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER,
"0123456789");
}
char const *x86_get_constraint_name(x86_asm_operand_kind_t const kind)
{
switch (kind) {
case ASM_OP_INVALID: return "invalid";
case ASM_OP_IN_REG: return "input register";
case ASM_OP_OUT_REG: return "output register";
case ASM_OP_MEMORY: return "memory";
case ASM_OP_IMMEDIATE: return "immediate";
}
panic("invalid constraint kind");
}
......@@ -67,4 +67,6 @@ ir_node *x86_match_ASM(ir_node const *node, x86_clobber_name_t const *names, x86
void x86_set_be_asm_constraint_support(const x86_asm_constraint_list_t *constraints);
char const *x86_get_constraint_name(x86_asm_operand_kind_t);
#endif
Supports Markdown
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