History

arm-asm: Implement asm_gen_code

Danny Milosavljevic committed 5 years ago

Commit 795d7d51 parent d66c1551 file · +80 −3Browse files

Unified · Split

arm-asm.c+80−3
@@ -1247,10 +1247,87 @@ ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier) · 1246 unmodified lines
12471247
12481248 /* generate prolog and epilog code for asm statement */
12491249 ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
1250− int nb_outputs, int is_output,
1251− uint8_t *clobber_regs,
1252− int out_reg)
1250+ int nb_outputs, int is_output,
1251+ uint8_t *clobber_regs,
1252+ int out_reg)
12531253 {
1254+ uint8_t regs_allocated[NB_ASM_REGS];
1255+ ASMOperand *op;
1256+ int i, reg;
1257+ uint32_t saved_regset = 0;
1258+
1259+ // TODO: Check non-E ABI.
1260+ // Note: Technically, r13 (sp) is also callee-saved--but that does not matter yet
1261+ static uint8_t reg_saved[] = { 4, 5, 6, 7, 8, 9 /* Note: sometimes special reg "sb" */ , 10, 11 };
1262+
1263+ /* mark all used registers */
1264+ memcpy(regs_allocated, clobber_regs, sizeof(regs_allocated));
1265+ for(i = 0; i < nb_operands;i++) {
1266+ op = &operands[i];
1267+ if (op->reg >= 0)
1268+ regs_allocated[op->reg] = 1;
1269+ }
1270+ for(i = 0; i < sizeof(reg_saved)/sizeof(reg_saved[0]); i++) {
1271+ reg = reg_saved[i];
1272+ if (regs_allocated[reg])
1273+ saved_regset |= 1 << reg;
1274+ }
1275+
1276+ if (!is_output) { // prolog
1277+ /* generate reg save code */
1278+ if (saved_regset)
1279+ gen_le32(0xe92d0000 | saved_regset); // push {...}
1280+
1281+ /* generate load code */
1282+ for(i = 0; i < nb_operands; i++) {
1283+ op = &operands[i];
1284+ if (op->reg >= 0) {
1285+ if ((op->vt->r & VT_VALMASK) == VT_LLOCAL &&
1286+ op->is_memory) {
1287+ /* memory reference case (for both input and
1288+ output cases) */
1289+ SValue sv;
1290+ sv = *op->vt;
1291+ sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL;
1292+ sv.type.t = VT_PTR;
1293+ load(op->reg, &sv);
1294+ } else if (i >= nb_outputs || op->is_rw) { // not write-only
1295+ /* load value in register */
1296+ load(op->reg, op->vt);
1297+ if (op->is_llong)
1298+ tcc_error("long long not implemented");
1299+ }
1300+ }
1301+ }
1302+ } else { // epilog
1303+ /* generate save code */
1304+ for(i = 0 ; i < nb_outputs; i++) {
1305+ op = &operands[i];
1306+ if (op->reg >= 0) {
1307+ if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) {
1308+ if (!op->is_memory) {
1309+ SValue sv;
1310+ sv = *op->vt;
1311+ sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
1312+ sv.type.t = VT_PTR;
1313+ load(out_reg, &sv);
1314+
1315+ sv = *op->vt;
1316+ sv.r = (sv.r & ~VT_VALMASK) | out_reg;
1317+ store(op->reg, &sv);
1318+ }
1319+ } else {
1320+ store(op->reg, op->vt);
1321+ if (op->is_llong)
1322+ tcc_error("long long not implemented");
1323+ }
1324+ }
1325+ }
1326+
1327+ /* generate reg restore code */
1328+ if (saved_regset)
1329+ gen_le32(0xe8bd0000 | saved_regset); // pop {...}
1330+ }
12541331 }
12551332
12561333 ST_FUNC void asm_compute_constraints(ASMOperand *operands,

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t