History

arm-asm: Raise error if more than two operands are specified on mov, mvn, cmp, cmn, tst, teq

Danny Milosavljevic committed 5 years ago

Commit 79567001 parent 612d9d71 file · +11 −5Browse files

Unified · Split

arm-asm.c+11−5
@@ -466,8 +466,9 @@ static void asm_data_processing_opcode(TCCState *s1, int token) · 465 unmodified lines
466 int nb_shift = 0;466 int nb_shift = 0;
467 uint32_t operands = 0;467 uint32_t operands = 0;
468 468
469 /* 16 entries per instruction for the different condition codes */469 /* modulo 16 entries per instruction for the different condition codes */
470 uint32_t opcode_idx = (ARM_INSTRUCTION_GROUP(token) - TOK_ASM_andeq) >> 4;470 uint32_t opcode_idx = (ARM_INSTRUCTION_GROUP(token) - TOK_ASM_andeq) >> 4;
471 uint32_t opcode_nos = opcode_idx >> 1; // without "s"; "OpCode" in ARM docs
471 472
472 for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ) {473 for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ) {
473 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)474 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)
@@ -517,6 +518,11 @@ static void asm_data_processing_opcode(TCCState *s1, int token) · 43 unmodified lines
517 memcpy(&ops[2], &ops[1], sizeof(ops[1])); // move ops[2]518 memcpy(&ops[2], &ops[1], sizeof(ops[1])); // move ops[2]
518 memcpy(&ops[1], &ops[0], sizeof(ops[0])); // ops[1] was implicit519 memcpy(&ops[1], &ops[0], sizeof(ops[0])); // ops[1] was implicit
519 nb_ops = 3;520 nb_ops = 3;
521 } else if (nb_ops == 3) {
522 if (opcode_nos == 0xd || opcode_nos == 0xf || opcode_nos == 0xa || opcode_nos == 0xb || opcode_nos == 0x8 || opcode_nos == 0x9) { // mov, mvn, cmp, cmn, tst, teq
523 tcc_error("'%s' cannot be used with three operands", get_tok_str(token, NULL));
524 return;
525 }
520 }526 }
521 if (nb_ops != 3) {527 if (nb_ops != 3) {
522 expect("two or three operands");528 expect("two or three operands");
@@ -533,16 +539,16 @@ static void asm_data_processing_opcode(TCCState *s1, int token) · 10 unmodified lines
533 // bits 24...21: "OpCode"--see below539 // bits 24...21: "OpCode"--see below
534 540
535 /* operations in the token list are ordered by opcode */541 /* operations in the token list are ordered by opcode */
536 opcode = (opcode_idx >> 1) << 21; // drop "s"542 opcode = opcode_nos << 21; // drop "s"
537 if (ops[0].type != OP_REG32)543 if (ops[0].type != OP_REG32)
538 expect("(destination operand) register");544 expect("(destination operand) register");
539 else if (opcode == 0xa << 21 || opcode == 0xb << 21 || opcode == 0x8 << 21 || opcode == 0x9 << 21 ) // cmp, cmn, tst, teq545 else if (opcode_nos == 0xa || opcode_nos == 0xb || opcode_nos == 0x8 || opcode_nos == 0x9) // cmp, cmn, tst, teq
540 operands |= ENCODE_SET_CONDITION_CODES; // force S set, otherwise it's a completely different instruction.546 operands |= ENCODE_SET_CONDITION_CODES; // force S set, otherwise it's a completely different instruction.
541 else547 else
542 operands |= ENCODE_RD(ops[0].reg);548 operands |= ENCODE_RD(ops[0].reg);
543 if (ops[1].type != OP_REG32)549 if (ops[1].type != OP_REG32)
544 expect("(first source operand) register");550 expect("(first source operand) register");
545 else if (!(opcode == 0xd << 21 || opcode == 0xf << 21)) // not: mov, mvn (those have only one source operand)551 else if (!(opcode_nos == 0xd || opcode_nos == 0xf)) // not: mov, mvn (those have only one source operand)
546 operands |= ENCODE_RN(ops[1].reg);552 operands |= ENCODE_RN(ops[1].reg);
547 switch (ops[2].type) {553 switch (ops[2].type) {
548 case OP_REG32:554 case OP_REG32:
@@ -562,7 +568,7 @@ static void asm_data_processing_opcode(TCCState *s1, int token) · 13 unmodified lines
562 1001 = TEQ - CC on: Op1 EOR Op2 -> difficult568 1001 = TEQ - CC on: Op1 EOR Op2 -> difficult
563 1100 = ORR - Rd:= Op1 OR Op2 -> difficult569 1100 = ORR - Rd:= Op1 OR Op2 -> difficult
564 */570 */
565 switch (opcode_idx >> 1) { // "OpCode" in ARM docs571 switch (opcode_nos) {
566#if 0572#if 0
567 case 0x0: // AND - Rd:= Op1 AND Op2573 case 0x0: // AND - Rd:= Op1 AND Op2
568 opcode = 0xe << 21; // BIC574 opcode = 0xe << 21; // BIC

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