Commit 6a01dd0a authored by Christoph Mallon's avatar Christoph Mallon
Browse files

be: Factor out (almost) common code in ${ARCH}_emitf() into the macro BE_EMITF().

This save quite a bit of code duplication.
Also the code drifted apart in the different backends, which this macro prevents now.
parent 24c5a97f
......@@ -63,23 +63,8 @@ static void TEMPLATE_emit_cfop_target(const ir_node *node)
void TEMPLATE_emitf(const ir_node *node, const char *format, ...)
{
va_list ap;
va_start(ap, format);
be_emit_char('\t');
for (;;) {
const char *start = format;
while (*format != '%' && *format != '\0')
++format;
be_emit_string_len(start, format-start);
if (*format == '\0')
break;
++format;
BE_EMITF(node, format, ap, false) {
switch (*format++) {
case '%':
be_emit_char('%');
break;
case 'S': {
if (!is_digit(*format))
goto unknown;
......@@ -129,20 +114,11 @@ void TEMPLATE_emitf(const ir_node *node, const char *format, ...)
break;
}
case '\n':
be_emit_char('\n');
be_emit_write_line();
be_emit_char('\t');
break;
default:
unknown:
panic("unknown format conversion");
}
}
va_end(ap);
be_emit_finish_line_gas(node);
}
/**
......
......@@ -332,31 +332,7 @@ static void emit_shiftop(const ir_node *const node)
void amd64_emitf(ir_node const *const node, char const *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
be_emit_char('\t');
for (;;) {
char const *start = fmt;
while (*fmt != '%' && *fmt != '\n' && *fmt != '\0')
++fmt;
if (fmt != start) {
be_emit_string_len(start, fmt - start);
}
if (*fmt == '\n') {
be_emit_char('\n');
be_emit_write_line();
be_emit_char('\t');
++fmt;
continue;
}
if (*fmt == '\0')
break;
++fmt;
BE_EMITF(node, fmt, ap, false) {
amd64_emit_mod_t mod = EMIT_NONE;
for (;;) {
switch (*fmt) {
......@@ -374,10 +350,6 @@ end_of_mods:
switch (*fmt++) {
arch_register_t const *reg;
case '%':
be_emit_char('%');
break;
case 'A':
switch (*fmt++) {
case 'F': {
......@@ -539,9 +511,6 @@ unknown:
panic("unknown format conversion");
}
}
be_emit_finish_line_gas(node);
va_end(ap);
}
static const char *get_register_name_ir_mode(const arch_register_t *reg,
......
......@@ -237,33 +237,8 @@ static void arm_emit_cfop_target(const ir_node *irn)
void arm_emitf(const ir_node *node, const char *format, ...)
{
va_list ap;
va_start(ap, format);
be_emit_char('\t');
for (;;) {
const char *start = format;
while (*format != '%' && *format != '\n' && *format != '\0')
++format;
be_emit_string_len(start, format - start);
if (*format == '\0')
break;
if (*format == '\n') {
++format;
be_emit_char('\n');
be_emit_write_line();
be_emit_char('\t');
continue;
}
++format;
BE_EMITF(node, format, ap, false) {
switch (*format++) {
case '%':
be_emit_char('%');
break;
case 'A':
arm_emit_address_mode(node);
break;
......@@ -357,8 +332,6 @@ unknown:
panic("unknown format conversion");
}
}
va_end(ap);
be_emit_finish_line_gas(node);
}
static ent_or_tv_t *get_ent_or_tv_entry(const ent_or_tv_t *key)
......
......@@ -39,7 +39,7 @@ void be_init_emitters(void);
void be_emit_nothing(ir_node const *node);
/**
* Emit code for a node by calling a handler registeres with be_set_emitter().
* Emit code for a node by calling a handler registered with be_set_emitter().
*/
void be_emit_node(ir_node const *node);
......
......@@ -96,4 +96,25 @@ static inline size_t be_emit_get_column(void)
return obstack_object_size(&emit_obst);
}
#define BE_EMITF(node, fmt, ap, in_delay_slot) \
va_list ap; \
va_start(ap, fmt); \
be_emit_char('\t'); \
if (in_delay_slot) \
be_emit_char(' '); \
for (size_t n;;) \
if (n = strcspn(fmt, "\n%"), be_emit_string_len(fmt, n), fmt += n, *fmt == '\0') { \
be_emit_finish_line_gas(node); \
va_end(ap); \
break; \
} else if (*fmt == '\n') { \
++fmt; \
be_emit_char('\n'); \
be_emit_write_line(); \
be_emit_char('\t'); \
} else if (*++fmt == '%') { \
++fmt; \
be_emit_char('%'); \
} else
#endif
......@@ -341,34 +341,8 @@ static void ia32_emit_am(ir_node const *const node)
void ia32_emitf(ir_node const *const node, char const *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
be_emit_char('\t');
for (;;) {
const char *start = fmt;
BE_EMITF(node, fmt, ap, false) {
ia32_emit_mod_t mod = EMIT_NONE;
while (*fmt != '%' && *fmt != '\n' && *fmt != '\0')
++fmt;
if (fmt != start) {
be_emit_string_len(start, fmt - start);
}
if (*fmt == '\n') {
be_emit_char('\n');
be_emit_write_line();
be_emit_char('\t');
++fmt;
if (*fmt == '\0')
break;
continue;
}
if (*fmt == '\0')
break;
++fmt;
for (;;) {
switch (*fmt) {
case '*': mod |= EMIT_ALTERNATE_AM; break;
......@@ -389,10 +363,6 @@ end_of_mods:
arch_register_t const *reg;
ir_node const *imm;
case '%':
be_emit_char('%');
break;
case 'A': {
switch (*fmt++) {
case 'F':
......@@ -627,9 +597,6 @@ unknown:
panic("unknown format conversion");
}
}
be_emit_finish_line_gas(node);
va_end(ap);
}
/**
......
......@@ -44,17 +44,6 @@ static pmap *delay_slots;
static bool emitting_delay_slot;
/**
* indent before instruction. (Adds additional indentation when emitting
* delay slots)
*/
static void sparc_emit_indent(void)
{
be_emit_char('\t');
if (emitting_delay_slot)
be_emit_char(' ');
}
static void sparc_emit_immediate(int32_t value, ir_entity *entity)
{
if (entity == NULL) {
......@@ -535,19 +524,7 @@ static ir_node *pick_delay_slot_for(ir_node *node)
void sparc_emitf(ir_node const *const node, char const *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
sparc_emit_indent();
for (;;) {
char const *start = fmt;
while (*fmt != '%' && *fmt != '\0')
++fmt;
be_emit_string_len(start, fmt - start);
if (*fmt == '\0')
break;
++fmt;
BE_EMITF(node, fmt, ap, emitting_delay_slot) {
bool plus = false;
if (*fmt == '+') {
plus = true;
......@@ -555,10 +532,6 @@ void sparc_emitf(ir_node const *const node, char const *fmt, ...)
}
switch (*fmt++) {
case '%':
be_emit_char('%');
break;
case 'A': {
const sparc_jmp_cond_attr_t *attr
= get_sparc_jmp_cond_attr_const(node);
......@@ -680,8 +653,6 @@ unknown:
panic("unknown format conversion in sparc_emitf()");
}
}
be_emit_finish_line_gas(node);
va_end(ap);
}
/**
......
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