History

arm-asm: Add mul, mla, smull, umull, smlal, umlal

Danny Milosavljevic committed 5 years ago

Commit 82663d31 parent c4e13c12 files · +190 −0Browse files

Unified · Split

2 files
  1. arm-asm.c +175 −0
  2. arm-tok.h +15 −0
arm-asm.c+175−0
@@ -286,6 +286,165 @@ static void asm_block_data_transfer_opcode(TCCState *s1, int token) · 285 unmodified lines
286 }286 }
287}287}
288 288
289static void asm_multiplication_opcode(TCCState *s1, int token)
290{
291 Operand ops[4];
292 int nb_ops = 0;
293 uint32_t opcode = 0x90;
294
295 for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) {
296 parse_operand(s1, &ops[nb_ops]);
297 if (tok != ',') {
298 ++nb_ops;
299 break;
300 }
301 next(); // skip ','
302 }
303 if (nb_ops < 2)
304 expect("at least two operands");
305 else if (nb_ops == 2) {
306 switch (ARM_INSTRUCTION_GROUP(token)) {
307 case TOK_ASM_mulseq:
308 case TOK_ASM_muleq:
309 memcpy(&ops[2], &ops[0], sizeof(ops[1])); // ARM is actually like this!
310 break;
311 default:
312 memcpy(&ops[2], &ops[1], sizeof(ops[1])); // move ops[2]
313 memcpy(&ops[1], &ops[0], sizeof(ops[0])); // ops[1] was implicit
314 }
315 nb_ops = 3;
316 }
317
318 // multiply (special case):
319 // operands:
320 // Rd: bits 19...16
321 // Rm: bits 3...0
322 // Rs: bits 11...8
323 // Rn: bits 15...12
324
325 if (ops[0].type == OP_REG32)
326 opcode |= ops[0].reg << 16;
327 else
328 expect("(destination operand) register");
329 if (ops[1].type == OP_REG32)
330 opcode |= ops[1].reg;
331 else
332 expect("(first source operand) register");
333 if (ops[2].type == OP_REG32)
334 opcode |= ops[2].reg << 8;
335 else
336 expect("(second source operand) register");
337 if (nb_ops > 3) {
338 if (ops[3].type == OP_REG32)
339 opcode |= ops[3].reg << 12;
340 else
341 expect("(third source operand) register");
342 }
343
344 switch (ARM_INSTRUCTION_GROUP(token)) {
345 case TOK_ASM_mulseq:
346 opcode |= 1 << 20; // Status
347 /* fallthrough */
348 case TOK_ASM_muleq:
349 if (nb_ops != 3)
350 expect("three operands");
351 else {
352 asm_emit_opcode(token, opcode);
353 }
354 break;
355 case TOK_ASM_mlaseq:
356 opcode |= 1 << 20; // Status
357 /* fallthrough */
358 case TOK_ASM_mlaeq:
359 if (nb_ops != 4)
360 expect("four operands");
361 else {
362 opcode |= 1 << 21; // Accumulate
363 asm_emit_opcode(token, opcode);
364 }
365 break;
366 default:
367 expect("known multiplication instruction");
368 }
369}
370
371static void asm_long_multiplication_opcode(TCCState *s1, int token)
372{
373 Operand ops[4];
374 int nb_ops = 0;
375 uint32_t opcode = 0x90 | (1 << 23);
376
377 for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) {
378 parse_operand(s1, &ops[nb_ops]);
379 if (tok != ',') {
380 ++nb_ops;
381 break;
382 }
383 next(); // skip ','
384 }
385 if (nb_ops != 4) {
386 expect("four operands");
387 return;
388 }
389
390 // long multiply (special case):
391 // operands:
392 // RdLo: bits 15...12
393 // RdHi: bits 19...16
394 // Rs: bits 11...8
395 // Rm: bits 3...0
396
397 if (ops[0].type == OP_REG32)
398 opcode |= ops[0].reg << 12;
399 else
400 expect("(destination lo accumulator) register");
401 if (ops[1].type == OP_REG32)
402 opcode |= ops[1].reg << 16;
403 else
404 expect("(destination hi accumulator) register");
405 if (ops[2].type == OP_REG32)
406 opcode |= ops[2].reg;
407 else
408 expect("(first source operand) register");
409 if (ops[3].type == OP_REG32)
410 opcode |= ops[3].reg << 8;
411 else
412 expect("(second source operand) register");
413
414 switch (ARM_INSTRUCTION_GROUP(token)) {
415 case TOK_ASM_smullseq:
416 opcode |= 1 << 20; // Status
417 /* fallthrough */
418 case TOK_ASM_smulleq:
419 opcode |= 1 << 22; // signed
420 asm_emit_opcode(token, opcode);
421 break;
422 case TOK_ASM_umullseq:
423 opcode |= 1 << 20; // Status
424 /* fallthrough */
425 case TOK_ASM_umulleq:
426 asm_emit_opcode(token, opcode);
427 break;
428 case TOK_ASM_smlalseq:
429 opcode |= 1 << 20; // Status
430 /* fallthrough */
431 case TOK_ASM_smlaleq:
432 opcode |= 1 << 22; // signed
433 opcode |= 1 << 21; // Accumulate
434 asm_emit_opcode(token, opcode);
435 break;
436 case TOK_ASM_umlalseq:
437 opcode |= 1 << 20; // Status
438 /* fallthrough */
439 case TOK_ASM_umlaleq:
440 opcode |= 1 << 21; // Accumulate
441 asm_emit_opcode(token, opcode);
442 break;
443 default:
444 expect("known long multiplication instruction");
445 }
446}
447
289ST_FUNC void asm_opcode(TCCState *s1, int token)448ST_FUNC void asm_opcode(TCCState *s1, int token)
290{449{
291 while (token == TOK_LINEFEED) {450 while (token == TOK_LINEFEED) {
@@ -315,6 +474,22 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 23 unmodified lines
315 case TOK_ASM_uxtbeq:474 case TOK_ASM_uxtbeq:
316 case TOK_ASM_uxtheq:475 case TOK_ASM_uxtheq:
317 return asm_binary_opcode(s1, token);476 return asm_binary_opcode(s1, token);
477
478 case TOK_ASM_muleq:
479 case TOK_ASM_mulseq:
480 case TOK_ASM_mlaeq:
481 case TOK_ASM_mlaseq:
482 return asm_multiplication_opcode(s1, token);
483
484 case TOK_ASM_smulleq:
485 case TOK_ASM_smullseq:
486 case TOK_ASM_umulleq:
487 case TOK_ASM_umullseq:
488 case TOK_ASM_smlaleq:
489 case TOK_ASM_smlalseq:
490 case TOK_ASM_umlaleq:
491 case TOK_ASM_umlalseq:
492 return asm_long_multiplication_opcode(s1, token);
318 default:493 default:
319 expect("known instruction");494 expect("known instruction");
320 }495 }
arm-tok.h+15−0
@@ -66,6 +66,21 @@ · 65 unmodified lines
66 DEF_ASM_CONDED(uxtb)66 DEF_ASM_CONDED(uxtb)
67 DEF_ASM_CONDED(uxth)67 DEF_ASM_CONDED(uxth)
68 68
69 /* multiplication */
70
71 DEF_ASM_CONDED(mul)
72 DEF_ASM_CONDED(muls)
73 DEF_ASM_CONDED(mla)
74 DEF_ASM_CONDED(mlas)
75 DEF_ASM_CONDED(smull)
76 DEF_ASM_CONDED(smulls)
77 DEF_ASM_CONDED(umull)
78 DEF_ASM_CONDED(umulls)
79 DEF_ASM_CONDED(smlal)
80 DEF_ASM_CONDED(smlals)
81 DEF_ASM_CONDED(umlal)
82 DEF_ASM_CONDED(umlals)
83
69 /* instruction macros */84 /* instruction macros */
70 85
71 DEF_ASM_CONDED(push)86 DEF_ASM_CONDED(push)

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