/* * translation routines; sometimes we pass data on * through directly (asm syntax->asm syntax, with * some macro expansion), and other times we also * do asm syntax->gas syntax translation */ #include "asmtrans.h" int syntax = GAS; char * immediate(op) char *op; { return concat("#", op); } char * indirect(op) char *op; { if (syntax == GAS) { return concat(op, "@"); } else { return concat3("(", op, ")"); } } char * postinc(op) char *op; { if (syntax == GAS) { return concat(op, "@+"); } else { return concat3("(", op, ")+"); } } char * predec(op) char *op; { if (syntax == GAS) { return concat(op, "@-"); } else { return concat3("-(", op, ")"); } } char * indexed(op1, op2) char *op1, *op2; { if (syntax == GAS) { return concat4(op2, "@(", op1, ")"); } else { return concat4(op1, "(", op2, ")"); } } char * sizedop(op, size) char *op, *size; { if (syntax == GAS) { return changesiz(concat(op, size)); } else { return concat4("(", op, ")", size); } } char * twoindex(disp, base, index) char *disp, *base, *index; { if (syntax == GAS) { return concat6(base, "@(", disp, ",", changesiz2(index), ")"); } else { return concat6(disp, "(", base, ",", index, ")"); } } char * bitfield(op1, op2, op3) char *op1, *op2, *op3; { if (syntax == GAS) { return concat6(op1, "{#", op2, ":#", op3, "}"); } else { return concat6(op1, "{", op2, ":", op3, "}"); } } char * postindex(bd, an , index, od) char *bd, *an, *index , *od; { if (syntax == GAS) { return concat8(an, "@(", bd, ")@(", od, ",", changesiz2(index), ")"); } else { return concat9("([",an, ",", bd, "],", index, ",", od ,")"); } } char * postindex0(bd) char *bd; { if (syntax == GAS) { return concat3("@(", bd, ")@()"); } else { return concat3("([", bd, "])"); } } char * postindex1(bd,od) char *bd, *od; { if (syntax == GAS) { return concat5("@(", bd, ")@(", od, ")"); } else { return concat5("([", bd, "],", od, ")"); } } char * preindex(bd, an , index, od) char *bd, *an, *index , *od; { if (syntax == GAS) { return concat8(an, "@(", bd, ",", changesiz2(index), ")@(", od, ")"); } else { return concat9("([",an, ",", bd, ",", index, "],", od, ")"); } } char * do_ops(label, opcode, space, operand) char *label, *opcode, *space, *operand; { static char temp[LINSIZ]; static char optemp[40]; char *to, *from; char c; if (syntax == GAS) { if (!strcmp(opcode, "ds.l")) { strcpy(temp, "\t.even\n\t.comm"); strcat(temp, space); strcat(temp, label); strcat(temp, ","); strcat(temp, "4*"); strcat(temp, operand); return strdup(temp); } else if (!strcmp(opcode, "ds.w")) { strcpy(temp, "\t.even\n\t.comm"); strcat(temp, space); strcat(temp, label); strcat(temp, ","); strcat(temp, "2*"); strcat(temp, operand); return strdup(temp); } else if (!strcmp(opcode, "ds.b")) { strcpy(temp, "\t.comm"); strcat(temp, space); strcat(temp, label); strcat(temp, ","); strcat(temp, operand); return strdup(temp); } else { to = optemp; from = opcode; for(;;) { c = *from++; if (!c) break; /* change 'foo.b' -> 'foob' */ /* special case: bra.s -> 'bra', since gas automatically * selects offset sizes and since some gas's actually * mess up if an explicit '.s' is given */ if (c == '.' && *from && from[1] == 0) { if (*from == 's') from++; continue; } *to++ = c; } *to = 0; opcode = optemp; } } to = temp; if (*label) { int colonseen = 0; char c; for (from = label; (c = *from++) != 0;) { if (c == ':') colonseen = 1; *to++ = c; } /* gas labels must have a ':' after them */ if (!colonseen && syntax == GAS) *to++ = ':'; } *to++ = '\t'; strcpy(to, opcode); strcat(temp, space); strcat(temp, operand); return strdup(temp); } char * changesiz(op) char *op; { char *r = op; if (syntax != GAS) return op; while (*op) { if (*op == '.') *op = ':'; op++; } return r; } char * changesiz2(op) /* rw: hack for scaled index */ char *op; { char *r = op; if (syntax != GAS) return op; while (*op) { if (*op == '.' || *op == '*' ) *op = ':'; op++; } return r; } char * hexop(op) char *op; { if (syntax == GAS) return concat("0x", op); else return concat("$", op); }