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
466466 int nb_shift = 0;
467467 uint32_t operands = 0;
468468
469− /* 16 entries per instruction for the different condition codes */
469+ /* modulo 16 entries per instruction for the different condition codes */
470470 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
471472
472473 for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ) {
473474 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
517518 memcpy(&ops[2], &ops[1], sizeof(ops[1])); // move ops[2]
518519 memcpy(&ops[1], &ops[0], sizeof(ops[0])); // ops[1] was implicit
519520 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+ }
520526 }
521527 if (nb_ops != 3) {
522528 expect("two or three operands");
@@ -533,16 +539,16 @@ static void asm_data_processing_opcode(TCCState *s1, int token) · 10 unmodified lines
533539 // bits 24...21: "OpCode"--see below
534540
535541 /* operations in the token list are ordered by opcode */
536− opcode = (opcode_idx >> 1) << 21; // drop "s"
542+ opcode = opcode_nos << 21; // drop "s"
537543 if (ops[0].type != OP_REG32)
538544 expect("(destination operand) register");
539− else if (opcode == 0xa << 21 || opcode == 0xb << 21 || opcode == 0x8 << 21 || opcode == 0x9 << 21 ) // cmp, cmn, tst, teq
545+ else if (opcode_nos == 0xa || opcode_nos == 0xb || opcode_nos == 0x8 || opcode_nos == 0x9) // cmp, cmn, tst, teq
540546 operands |= ENCODE_SET_CONDITION_CODES; // force S set, otherwise it's a completely different instruction.
541547 else
542548 operands |= ENCODE_RD(ops[0].reg);
543549 if (ops[1].type != OP_REG32)
544550 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)
546552 operands |= ENCODE_RN(ops[1].reg);
547553 switch (ops[2].type) {
548554 case OP_REG32:
@@ -562,7 +568,7 @@ static void asm_data_processing_opcode(TCCState *s1, int token) · 13 unmodified lines
562568 1001 = TEQ - CC on: Op1 EOR Op2 -> difficult
563569 1100 = ORR - Rd:= Op1 OR Op2 -> difficult
564570 */
565− switch (opcode_idx >> 1) { // "OpCode" in ARM docs
571+ switch (opcode_nos) {
566572 #if 0
567573 case 0x0: // AND - Rd:= Op1 AND Op2
568574 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