/[qemu]/qemu/translate-arm.c
ViewVC logotype

Diff of /qemu/translate-arm.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.2 by bellard, Tue Jun 24 13:28:48 2003 UTC revision 1.3 by bellard, Wed Jul 9 17:10:32 2003 UTC
# Line 34  typedef struct DisasContext { Line 34  typedef struct DisasContext {
34      struct TranslationBlock *tb;      struct TranslationBlock *tb;
35  } DisasContext;  } DisasContext;
36    
37    #define DISAS_JUMP_NEXT 4
38    
39  /* XXX: move that elsewhere */  /* XXX: move that elsewhere */
40  static uint16_t *gen_opc_ptr;  static uint16_t *gen_opc_ptr;
41  static uint32_t *gen_opparam_ptr;  static uint32_t *gen_opparam_ptr;
# Line 333  static void disas_arm_insn(DisasContext Line 335  static void disas_arm_insn(DisasContext
335          /* if not always execute, we generate a conditional jump to          /* if not always execute, we generate a conditional jump to
336             next instruction */             next instruction */
337          gen_test_cc[cond ^ 1]((long)s->tb, (long)s->pc);          gen_test_cc[cond ^ 1]((long)s->tb, (long)s->pc);
338          s->is_jmp = 1;          s->is_jmp = DISAS_JUMP_NEXT;
339      }      }
340      if ((insn & 0x0c000000) == 0 &&      if (((insn & 0x0e000000) == 0 &&
341          (insn & 0x00000090) != 0x90) {           (insn & 0x00000090) != 0x90) ||
342            ((insn & 0x0e000000) == (1 << 25))) {
343          int set_cc, logic_cc, shiftop;          int set_cc, logic_cc, shiftop;
344                    
345          op1 = (insn >> 21) & 0xf;          op1 = (insn >> 21) & 0xf;
# Line 367  static void disas_arm_insn(DisasContext Line 370  static void disas_arm_insn(DisasContext
370                      }                      }
371                  }                  }
372              } else {              } else {
373                  rs = (insn >> 16) & 0xf;                  rs = (insn >> 8) & 0xf;
374                  gen_movl_T0_reg(s, rs);                  gen_movl_T0_reg(s, rs);
375                  if (logic_cc) {                  if (logic_cc) {
376                      gen_shift_T1_T0_cc[shiftop]();                      gen_shift_T1_T0_cc[shiftop]();
# Line 385  static void disas_arm_insn(DisasContext Line 388  static void disas_arm_insn(DisasContext
388          case 0x00:          case 0x00:
389              gen_op_andl_T0_T1();              gen_op_andl_T0_T1();
390              gen_movl_reg_T0(s, rd);              gen_movl_reg_T0(s, rd);
391                if (logic_cc)
392                    gen_op_logic_T0_cc();
393              break;              break;
394          case 0x01:          case 0x01:
395              gen_op_xorl_T0_T1();              gen_op_xorl_T0_T1();
396              gen_movl_reg_T0(s, rd);              gen_movl_reg_T0(s, rd);
397                if (logic_cc)
398                    gen_op_logic_T0_cc();
399              break;              break;
400          case 0x02:          case 0x02:
401              if (set_cc)              if (set_cc)
# Line 435  static void disas_arm_insn(DisasContext Line 442  static void disas_arm_insn(DisasContext
442          case 0x08:          case 0x08:
443              if (set_cc) {              if (set_cc) {
444                  gen_op_andl_T0_T1();                  gen_op_andl_T0_T1();
445                    gen_op_logic_T0_cc();
446              }              }
447              break;              break;
448          case 0x09:          case 0x09:
449              if (set_cc) {              if (set_cc) {
450                  gen_op_xorl_T0_T1();                  gen_op_xorl_T0_T1();
451                    gen_op_logic_T0_cc();
452              }              }
453              break;              break;
454          case 0x0a:          case 0x0a:
# Line 455  static void disas_arm_insn(DisasContext Line 464  static void disas_arm_insn(DisasContext
464          case 0x0c:          case 0x0c:
465              gen_op_orl_T0_T1();              gen_op_orl_T0_T1();
466              gen_movl_reg_T0(s, rd);              gen_movl_reg_T0(s, rd);
467                if (logic_cc)
468                    gen_op_logic_T0_cc();
469              break;              break;
470          case 0x0d:          case 0x0d:
471              gen_movl_reg_T1(s, rd);              gen_movl_reg_T1(s, rd);
472                if (logic_cc)
473                    gen_op_logic_T1_cc();
474              break;              break;
475          case 0x0e:          case 0x0e:
476              gen_op_bicl_T0_T1();              gen_op_bicl_T0_T1();
477              gen_movl_reg_T0(s, rd);              gen_movl_reg_T0(s, rd);
478                if (logic_cc)
479                    gen_op_logic_T0_cc();
480              break;              break;
481          default:          default:
482          case 0x0f:          case 0x0f:
483              gen_op_notl_T1();              gen_op_notl_T1();
484              gen_movl_reg_T1(s, rd);              gen_movl_reg_T1(s, rd);
485                if (logic_cc)
486                    gen_op_logic_T1_cc();
487              break;              break;
488          }          }
         if (logic_cc)  
             gen_op_logic_cc();  
489      } else {      } else {
490          /* other instructions */          /* other instructions */
491          op1 = (insn >> 24) & 0xf;          op1 = (insn >> 24) & 0xf;
# Line 494  static void disas_arm_insn(DisasContext Line 509  static void disas_arm_insn(DisasContext
509                              gen_op_addl_T0_T1();                              gen_op_addl_T0_T1();
510                          }                          }
511                          if (insn & (1 << 20))                          if (insn & (1 << 20))
512                              gen_op_logic_cc();                              gen_op_logic_T0_cc();
513                          gen_movl_reg_T0(s, rd);                          gen_movl_reg_T0(s, rd);
514                      } else {                      } else {
515                          /* 64 bit mul */                          /* 64 bit mul */
# Line 551  static void disas_arm_insn(DisasContext Line 566  static void disas_arm_insn(DisasContext
566                      /* store */                      /* store */
567                      gen_op_stw_T0_T1();                      gen_op_stw_T0_T1();
568                  }                  }
569                  if (!(insn & (1 << 24)))                  if (!(insn & (1 << 24))) {
570                      gen_add_datah_offset(s, insn);                      gen_add_datah_offset(s, insn);
                 if (insn & (1 << 21))  
571                      gen_movl_reg_T1(s, rn);                      gen_movl_reg_T1(s, rn);
572                    } else if (insn & (1 << 21)) {
573                        gen_movl_reg_T1(s, rn);
574                    }
575              }              }
576              break;              break;
577          case 0x4:          case 0x4:
# Line 582  static void disas_arm_insn(DisasContext Line 599  static void disas_arm_insn(DisasContext
599                  else                  else
600                      gen_op_stl_T0_T1();                      gen_op_stl_T0_T1();
601              }              }
602              if (!(insn & (1 << 24)))              if (!(insn & (1 << 24))) {
603                  gen_add_data_offset(s, insn);                  gen_add_data_offset(s, insn);
             if (insn & (1 << 21))  
604                  gen_movl_reg_T1(s, rn);                  gen_movl_reg_T1(s, rn);
605                } else if (insn & (1 << 21))
606                    gen_movl_reg_T1(s, rn); {
607                }
608              break;              break;
609          case 0x08:          case 0x08:
610          case 0x09:          case 0x09:
611              /* load/store multiple words */              {
612              if (insn & (1 << 22))                  int j, n;
613                  goto illegal_op; /* only usable in supervisor mode */                  /* load/store multiple words */
614              rn = (insn >> 16) & 0xf;                  /* XXX: store correct base if write back */
615              gen_movl_T1_reg(s, rn);                  if (insn & (1 << 22))
616              val = 4;                      goto illegal_op; /* only usable in supervisor mode */
617              if (!(insn & (1 << 23)))                  rn = (insn >> 16) & 0xf;
618                  val = -val;                  gen_movl_T1_reg(s, rn);
619              for(i=0;i<16;i++) {                  
620                  if (insn & (1 << i)) {                  /* compute total size */
621                      if (insn & (1 << 24))                  n = 0;
622                          gen_op_addl_T1_im(val);                  for(i=0;i<16;i++) {
623                      if (insn & (1 << 20)) {                      if (insn & (1 << i))
624                          /* load */                          n++;
625                          gen_op_ldl_T0_T1();                  }
626                          gen_movl_reg_T0(s, i);                  /* XXX: test invalid n == 0 case ? */
627                    if (insn & (1 << 23)) {
628                        if (insn & (1 << 24)) {
629                            /* pre increment */
630                            gen_op_addl_T1_im(4);
631                      } else {                      } else {
632                          /* store */                          /* post increment */
633                          gen_movl_T0_reg(s, i);                      }
634                          gen_op_stl_T0_T1();                  } else {
635                        if (insn & (1 << 24)) {
636                            /* pre decrement */
637                            gen_op_addl_T1_im(-(n * 4));
638                        } else {
639                            /* post decrement */
640                            if (n != 1)
641                                gen_op_addl_T1_im(-((n - 1) * 4));
642                        }
643                    }
644                    j = 0;
645                    for(i=0;i<16;i++) {
646                        if (insn & (1 << i)) {
647                            if (insn & (1 << 20)) {
648                                /* load */
649                                gen_op_ldl_T0_T1();
650                                gen_movl_reg_T0(s, i);
651                            } else {
652                                /* store */
653                                if (i == 15) {
654                                    /* special case: r15 = PC + 12 */
655                                    val = (long)s->pc + 8;
656                                    gen_op_movl_TN_im[0](val);
657                                } else {
658                                    gen_movl_T0_reg(s, i);
659                                }
660                                gen_op_stl_T0_T1();
661                            }
662                            j++;
663                            /* no need to add after the last transfer */
664                            if (j != n)
665                                gen_op_addl_T1_im(4);
666                      }                      }
667                      if (!(insn & (1 << 24)))                  }
668                          gen_op_addl_T1_im(val);                  if (insn & (1 << 21)) {
669                        /* write back */
670                        if (insn & (1 << 23)) {
671                            if (insn & (1 << 24)) {
672                                /* pre increment */
673                            } else {
674                                /* post increment */
675                                gen_op_addl_T1_im(4);
676                            }
677                        } else {
678                            if (insn & (1 << 24)) {
679                                /* pre decrement */
680                                if (n != 1)
681                                    gen_op_addl_T1_im(-((n - 1) * 4));
682                            } else {
683                                /* post decrement */
684                                gen_op_addl_T1_im(-(n * 4));
685                            }
686                        }
687                        gen_movl_reg_T1(s, rn);
688                  }                  }
689              }              }
             if (insn & (1 << 21))  
                 gen_movl_reg_T1(s, rn);  
690              break;              break;
691          case 0xa:          case 0xa:
692          case 0xb:          case 0xb:
# Line 641  static void disas_arm_insn(DisasContext Line 712  static void disas_arm_insn(DisasContext
712              gen_op_swi();              gen_op_swi();
713              s->is_jmp = DISAS_JUMP;              s->is_jmp = DISAS_JUMP;
714              break;              break;
715            case 0xc:
716            case 0xd:
717                rd = (insn >> 12) & 0x7;
718                rn = (insn >> 16) & 0xf;
719                gen_movl_T1_reg(s, rn);
720                val = (insn) & 0xff;
721                if (!(insn & (1 << 23)))
722                    val = -val;
723                switch((insn >> 8) & 0xf) {
724                case 0x1:
725                    /* load/store */
726                    if ((insn & (1 << 24)))
727                        gen_op_addl_T1_im(val);
728                    /* XXX: do it */
729                    if (!(insn & (1 << 24)))
730                        gen_op_addl_T1_im(val);
731                    if (insn & (1 << 21))
732                        gen_movl_reg_T1(s, rn);
733                    break;
734                case 0x2:
735                    {
736                        int n, i;
737                        /* load store multiple */
738                        if ((insn & (1 << 24)))
739                            gen_op_addl_T1_im(val);
740                        switch(insn & 0x00408000) {
741                        case 0x00008000: n = 1; break;
742                        case 0x00400000: n = 2; break;
743                        case 0x00408000: n = 3; break;
744                        default: n = 4; break;
745                        }
746                        for(i = 0;i < n; i++) {
747                            /* XXX: do it */
748                        }
749                        if (!(insn & (1 << 24)))
750                            gen_op_addl_T1_im(val);
751                        if (insn & (1 << 21))
752                            gen_movl_reg_T1(s, rn);
753                    }
754                    break;
755                default:
756                    goto illegal_op;
757                }
758                break;
759            case 0x0e:
760                /* float ops */
761                /* XXX: do it */
762                switch((insn >> 20) & 0xf) {
763                case 0x2: /* wfs */
764                    break;
765                case 0x3: /* rfs */
766                    break;
767                case 0x4: /* wfc */
768                    break;
769                case 0x5: /* rfc */
770                    break;
771                default:
772                    goto illegal_op;
773                }
774                break;
775          default:          default:
776          illegal_op:          illegal_op:
777              gen_op_movl_T0_im((long)s->pc - 4);              gen_op_movl_T0_im((long)s->pc - 4);
# Line 688  static inline int gen_intermediate_code_ Line 819  static inline int gen_intermediate_code_
819          disas_arm_insn(dc);          disas_arm_insn(dc);
820      } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&      } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
821               (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));               (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
822      /* we must store the eflags state if it is not already done */      switch(dc->is_jmp) {
823      if (dc->is_jmp != DISAS_TB_JUMP &&      case DISAS_JUMP_NEXT:
824          dc->is_jmp != DISAS_JUMP) {      case DISAS_NEXT:
825          gen_op_movl_T0_im((long)dc->pc - 4);          gen_op_jmp((long)dc->tb, (long)dc->pc);
826          gen_op_movl_reg_TN[0][15]();          break;
827      }      default:
828      if (dc->is_jmp != DISAS_TB_JUMP) {      case DISAS_JUMP:
829          /* indicate that the hash table must be used to find the next TB */          /* indicate that the hash table must be used to find the next TB */
830          gen_op_movl_T0_0();          gen_op_movl_T0_0();
831            break;
832        case DISAS_TB_JUMP:
833            /* nothing more to generate */
834            break;
835      }      }
836      *gen_opc_ptr = INDEX_op_end;      *gen_opc_ptr = INDEX_op_end;
837    
# Line 756  void cpu_arm_dump_state(CPUARMState *env Line 891  void cpu_arm_dump_state(CPUARMState *env
891          else          else
892              fprintf(f, " ");              fprintf(f, " ");
893      }      }
894      fprintf(f, "CPSR=%08x", env->cpsr);      fprintf(f, "PSR=%08x %c%c%c%c\n",
895                env->cpsr,
896                env->cpsr & (1 << 31) ? 'N' : '-',
897                env->cpsr & (1 << 30) ? 'Z' : '-',
898                env->cpsr & (1 << 29) ? 'C' : '-',
899                env->cpsr & (1 << 28) ? 'V' : '-');
900  }  }

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26