Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* -----------------------------------------------------------------------------
  2.  * syn-intel.c
  3.  *
  4.  * Copyright (c) 2002, 2003, 2004 Vivek Mohan <vivek@sig9.com>
  5.  * All rights reserved. See (LICENSE)
  6.  * -----------------------------------------------------------------------------
  7.  */
  8.  
  9. #include "types.h"
  10. #include "extern.h"
  11. #include "decode.h"
  12. #include "itab.h"
  13. #include "syn.h"
  14.  
  15. /* -----------------------------------------------------------------------------
  16.  * opr_cast() - Prints an operand cast.
  17.  * -----------------------------------------------------------------------------
  18.  */
  19. static void
  20. opr_cast(struct ud* u, struct ud_operand* op)
  21. {
  22.   switch(op->size) {
  23.         case  8: mkasm(u, "byte " ); break;
  24.         case 16: mkasm(u, "word " ); break;
  25.         case 32: mkasm(u, "dword "); break;
  26.         case 64: mkasm(u, "qword "); break;
  27.         case 80: mkasm(u, "tword "); break;
  28.         default: break;
  29.   }
  30.   if (u->br_far)
  31.         mkasm(u, "far ");
  32.   else if (u->br_near)
  33.         mkasm(u, "near ");
  34. }
  35.  
  36. /* -----------------------------------------------------------------------------
  37.  * gen_operand() - Generates assembly output for each operand.
  38.  * -----------------------------------------------------------------------------
  39.  */
  40. static void gen_operand(struct ud* u, struct ud_operand* op, int syn_cast)
  41. {
  42.   switch(op->type) {
  43.         case UD_OP_REG:
  44.                 mkasm(u, ud_reg_tab[op->base - UD_R_AL]);
  45.                 break;
  46.  
  47.         case UD_OP_MEM: {
  48.  
  49.                 int op_f = 0;
  50.  
  51.                 if (syn_cast)
  52.                         opr_cast(u, op);
  53.  
  54.                 mkasm(u, "[");
  55.  
  56.                 if (u->pfx_seg)
  57.                         mkasm(u, "%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]);
  58.  
  59.                 if (op->base) {
  60.                         mkasm(u, "%s", ud_reg_tab[op->base - UD_R_AL]);
  61.                         op_f = 1;
  62.                 }
  63.  
  64.                 if (op->index) {
  65.                         if (op_f)
  66.                                 mkasm(u, "+");
  67.                         mkasm(u, "%s", ud_reg_tab[op->index - UD_R_AL]);
  68.                         op_f = 1;
  69.                 }
  70.  
  71.                 if (op->scale)
  72.                         mkasm(u, "*%d", op->scale);
  73.  
  74.                 if (op->offset == 8) {
  75.                         if (op->lval.sbyte < 0)
  76.                                 mkasm(u, "-0x%x", -op->lval.sbyte);
  77.                         else    mkasm(u, "%s0x%x", (op_f) ? "+" : "", op->lval.sbyte);
  78.                 }
  79.                 else if (op->offset == 16)
  80.                         mkasm(u, "%s0x%x", (op_f) ? "+" : "", op->lval.uword);
  81.                 else if (op->offset == 32) {
  82.                         if (u->adr_mode == 64) {
  83.                                 if (op->lval.sdword < 0)
  84.                                         mkasm(u, "-0x%x", -op->lval.sdword);
  85.                                 else    mkasm(u, "%s0x%x", (op_f) ? "+" : "", op->lval.sdword);
  86.                         }
  87.                         else    mkasm(u, "%s0x%lx", (op_f) ? "+" : "", op->lval.udword);
  88.                 }
  89.                 else if (op->offset == 64)
  90.                         mkasm(u, "%s0x" FMT64 "x", (op_f) ? "+" : "", op->lval.uqword);
  91.  
  92.                 mkasm(u, "]");
  93.                 break;
  94.         }
  95.                        
  96.         case UD_OP_IMM:
  97.                 if (syn_cast) opr_cast(u, op);
  98.                 switch (op->size) {
  99.                         case  8: mkasm(u, "0x%x", op->lval.ubyte);    break;
  100.                         case 16: mkasm(u, "0x%x", op->lval.uword);    break;
  101.                         case 32: mkasm(u, "0x%lx", op->lval.udword);  break;
  102.                         case 64: mkasm(u, "0x" FMT64 "x", op->lval.uqword); break;
  103.                         default: break;
  104.                 }
  105.                 break;
  106.  
  107.         case UD_OP_JIMM:
  108.                 if (syn_cast) opr_cast(u, op);
  109.                 switch (op->size) {
  110.                         case  8:
  111.                                 mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sbyte);
  112.                                 break;
  113.                         case 16:
  114.                                 mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sword);
  115.                                 break;
  116.                         case 32:
  117.                                 mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sdword);
  118.                                 break;
  119.                         default:break;
  120.                 }
  121.                 break;
  122.  
  123.         case UD_OP_PTR:
  124.                 switch (op->size) {
  125.                         case 32:
  126.                                 mkasm(u, "word 0x%x:0x%x", op->lval.ptr.seg,
  127.                                         op->lval.ptr.off & 0xFFFF);
  128.                                 break;
  129.                         case 48:
  130.                                 mkasm(u, "dword 0x%x:0x%lx", op->lval.ptr.seg,
  131.                                         op->lval.ptr.off);
  132.                                 break;
  133.                 }
  134.                 break;
  135.  
  136.         case UD_OP_CONST:
  137.                 if (syn_cast) opr_cast(u, op);
  138.                 mkasm(u, "%d", op->lval.udword);
  139.                 break;
  140.  
  141.         default: return;
  142.   }
  143. }
  144.  
  145. /* =============================================================================
  146.  * translates to intel syntax
  147.  * =============================================================================
  148.  */
  149. extern void ud_translate_intel(struct ud* u)
  150. {
  151.   /* -- prefixes -- */
  152.  
  153.   /* check if P_OSO prefix is used */
  154.   if (! P_OSO(u->itab_entry->prefix) && u->pfx_opr) {
  155.         switch (u->dis_mode) {
  156.                 case 16:
  157.                         mkasm(u, "o32 ");
  158.                         break;
  159.                 case 32:
  160.                 case 64:
  161.                         mkasm(u, "o16 ");
  162.                         break;
  163.         }
  164.   }
  165.  
  166.   /* check if P_ASO prefix was used */
  167.   if (! P_ASO(u->itab_entry->prefix) && u->pfx_adr) {
  168.         switch (u->dis_mode) {
  169.                 case 16:
  170.                         mkasm(u, "a32 ");
  171.                         break;
  172.                 case 32:
  173.                         mkasm(u, "a16 ");
  174.                         break;
  175.                 case 64:
  176.                         mkasm(u, "a32 ");
  177.                         break;
  178.         }
  179.   }
  180.  
  181.   if (u->pfx_lock)
  182.         mkasm(u, "lock ");
  183.   if (u->pfx_rep)
  184.         mkasm(u, "rep ");
  185.   if (u->pfx_repne)
  186.         mkasm(u, "repne ");
  187.   if (u->implicit_addr && u->pfx_seg)
  188.         mkasm(u, "%s ", ud_reg_tab[u->pfx_seg - UD_R_AL]);
  189.  
  190.   /* print the instruction mnemonic */
  191.   mkasm(u, "%s ", ud_lookup_mnemonic(u->mnemonic));
  192.  
  193.   /* operand 1 */
  194.   if (u->operand[0].type != UD_NONE) {
  195.         gen_operand(u, &u->operand[0], u->c1);
  196.   }
  197.   /* operand 2 */
  198.   if (u->operand[1].type != UD_NONE) {
  199.         mkasm(u, ", ");
  200.         gen_operand(u, &u->operand[1], u->c2);
  201.   }
  202.  
  203.   /* operand 3 */
  204.   if (u->operand[2].type != UD_NONE) {
  205.         mkasm(u, ", ");
  206.         gen_operand(u, &u->operand[2], u->c3);
  207.   }
  208. }
  209.