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
1247 1247
1248/* generate prolog and epilog code for asm statement */1248/* generate prolog and epilog code for asm statement */
1249ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,1249ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
1250 int nb_outputs, int is_output,1250 int nb_outputs, int is_output,
1251 uint8_t *clobber_regs,1251 uint8_t *clobber_regs,
1252 int out_reg)1252 int out_reg)
1253{1253{
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 }
1254}1331}
1255 1332
1256ST_FUNC void asm_compute_constraints(ASMOperand *operands,1333ST_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