History

arm-asm: For data processing instructions, support shifts and rotations.

Danny Milosavljevic committed 5 years ago

Commit daaa88c1 parent abef8f62 files · +52 −8Browse files

Unified · Split

2 files
  1. arm-asm.c +48 −8
  2. arm-tok.h +4 −0
arm-asm.c+48−8
@@ -413,18 +413,55 @@ static void asm_data_processing_opcode(TCCState *s1, int token) · 412 unmodified lines
413{413{
414 Operand ops[3];414 Operand ops[3];
415 int nb_ops;415 int nb_ops;
416 Operand shift = {};
417 int nb_shift = 0;
418 uint32_t operands = 0;
416 419
417 /* 16 entries per instruction for the different condition codes */420 /* 16 entries per instruction for the different condition codes */
418 uint32_t opcode_idx = (ARM_INSTRUCTION_GROUP(token) - TOK_ASM_andeq) >> 4;421 uint32_t opcode_idx = (ARM_INSTRUCTION_GROUP(token) - TOK_ASM_andeq) >> 4;
419 422
420 for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) {423 for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ) {
424 if (tok == TOK_ASM_asl || tok == TOK_ASM_lsl || tok == TOK_ASM_lsr || tok == TOK_ASM_asr || tok == TOK_ASM_ror || tok == TOK_ASM_rrx)
425 break;
421 parse_operand(s1, &ops[nb_ops]);426 parse_operand(s1, &ops[nb_ops]);
422 if (tok != ',') {427 ++nb_ops;
423 ++nb_ops;428 if (tok != ',')
424 break;429 break;
425 }
426 next(); // skip ','430 next(); // skip ','
427 }431 }
432 if (tok == ',')
433 next();
434 switch (tok) {
435 case TOK_ASM_asl:
436 case TOK_ASM_lsl:
437 case TOK_ASM_asr:
438 case TOK_ASM_lsr:
439 case TOK_ASM_ror:
440 switch (tok) {
441 case TOK_ASM_asl:
442 /* fallthrough */
443 case TOK_ASM_lsl:
444 operands |= ENCODE_BARREL_SHIFTER_MODE_LSL;
445 break;
446 case TOK_ASM_asr:
447 operands |= ENCODE_BARREL_SHIFTER_MODE_ASR;
448 break;
449 case TOK_ASM_lsr:
450 operands |= ENCODE_BARREL_SHIFTER_MODE_LSR;
451 break;
452 case TOK_ASM_ror:
453 operands |= ENCODE_BARREL_SHIFTER_MODE_ROR;
454 break;
455 }
456 next();
457 parse_operand(s1, &shift);
458 nb_shift = 1;
459 break;
460 case TOK_ASM_rrx:
461 next();
462 operands |= ENCODE_BARREL_SHIFTER_MODE_ROR;
463 break;
464 }
428 if (nb_ops < 2)465 if (nb_ops < 2)
429 expect("at least two operands");466 expect("at least two operands");
430 else if (nb_ops == 2) {467 else if (nb_ops == 2) {
@@ -437,7 +474,6 @@ static void asm_data_processing_opcode(TCCState *s1, int token) · 6 unmodified lines
437 return;474 return;
438 } else {475 } else {
439 uint32_t opcode = 0;476 uint32_t opcode = 0;
440 uint32_t operands = 0;
441 477
442 // data processing (general case):478 // data processing (general case):
443 // operands:479 // operands:
@@ -461,16 +497,13 @@ static void asm_data_processing_opcode(TCCState *s1, int token) · 17 unmodified lines
461 operands |= ENCODE_RN(ops[1].reg);497 operands |= ENCODE_RN(ops[1].reg);
462 switch (ops[2].type) {498 switch (ops[2].type) {
463 case OP_REG32:499 case OP_REG32:
464 // TODO: Parse and encode shift.
465 operands |= ops[2].reg;500 operands |= ops[2].reg;
466 break;501 break;
467 case OP_IM8:502 case OP_IM8:
468 // TODO: Parse and encode rotation.
469 operands |= ENCODE_IMMEDIATE_FLAG;503 operands |= ENCODE_IMMEDIATE_FLAG;
470 operands |= ops[2].e.v;504 operands |= ops[2].e.v;
471 break;505 break;
472 case OP_IM8N: // immediate negative value506 case OP_IM8N: // immediate negative value
473 // TODO: Parse and encode rotation.
474 operands |= ENCODE_IMMEDIATE_FLAG;507 operands |= ENCODE_IMMEDIATE_FLAG;
475 /* Instruction swapping:508 /* Instruction swapping:
476 0001 = EOR - Rd:= Op1 EOR Op2 -> difficult509 0001 = EOR - Rd:= Op1 EOR Op2 -> difficult
@@ -534,6 +567,13 @@ static void asm_data_processing_opcode(TCCState *s1, int token) · 57 unmodified lines
534 expect("(second source operand) register or immediate value");567 expect("(second source operand) register or immediate value");
535 }568 }
536 569
570 if (nb_shift) {
571 if (operands & ENCODE_IMMEDIATE_FLAG)
572 tcc_error("immediate rotation not implemented");
573 else
574 operands |= asm_encode_shift(&shift);
575 }
576
537 /* S=0 and S=1 entries alternate one after another, in that order */577 /* S=0 and S=1 entries alternate one after another, in that order */
538 opcode |= (opcode_idx & 1) ? ENCODE_SET_CONDITION_CODES : 0;578 opcode |= (opcode_idx & 1) ? ENCODE_SET_CONDITION_CODES : 0;
539 asm_emit_opcode(token, opcode | operands);579 asm_emit_opcode(token, opcode | operands);
arm-tok.h+4−0
@@ -28,6 +28,10 @@ · 27 unmodified lines
28 DEF_ASM(lr) /* alias for r14 */28 DEF_ASM(lr) /* alias for r14 */
29 DEF_ASM(pc) /* alias for r15 */29 DEF_ASM(pc) /* alias for r15 */
30 30
31 /* data processing directives */
32
33 DEF_ASM(asl)
34
31#define ARM_INSTRUCTION_GROUP(tok) ((((tok) - TOK_ASM_nopeq) & 0xFFFFFFF0) + TOK_ASM_nopeq)35#define ARM_INSTRUCTION_GROUP(tok) ((((tok) - TOK_ASM_nopeq) & 0xFFFFFFF0) + TOK_ASM_nopeq)
32 36
33/* Note: condition code is 4 bits */37/* Note: condition code is 4 bits */

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