Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* -----------------------------------------------------------------------------
  2.  * syn-att.c
  3.  *
  4.  * Copyright (c) 2004, 2005, 2006 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 16 : case 32 :
  24.                 mkasm(u, "*");   break;
  25.         default: break;
  26.   }
  27. }
  28.  
  29. /* -----------------------------------------------------------------------------
  30.  * gen_operand() - Generates assembly output for each operand.
  31.  * -----------------------------------------------------------------------------
  32.  */
  33. static void
  34. gen_operand(struct ud* u, struct ud_operand* op)
  35. {
  36.   switch(op->type) {
  37.         case UD_OP_REG:
  38.                 mkasm(u, "%%%s", ud_reg_tab[op->base - UD_R_AL]);
  39.                 break;
  40.  
  41.         case UD_OP_MEM:
  42.                 if (u->br_far) opr_cast(u, op);
  43.                 if (u->pfx_seg)
  44.                         mkasm(u, "%%%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]);
  45.                 if (op->offset == 8) {
  46.                         if (op->lval.sbyte < 0)
  47.                                 mkasm(u, "-0x%x", (-op->lval.sbyte) & 0xff);
  48.                         else    mkasm(u, "0x%x", op->lval.sbyte);
  49.                 }
  50.                 else if (op->offset == 16)
  51.                         mkasm(u, "0x%x", op->lval.uword);
  52.                 else if (op->offset == 32)
  53.                         mkasm(u, "0x%lx", op->lval.udword);
  54.                 else if (op->offset == 64)
  55.                         mkasm(u, "0x" FMT64 "x", op->lval.uqword);
  56.  
  57.                 if (op->base)
  58.                         mkasm(u, "(%%%s", ud_reg_tab[op->base - UD_R_AL]);
  59.                 if (op->index) {
  60.                         if (op->base)
  61.                                 mkasm(u, ",");
  62.                         else mkasm(u, "(");
  63.                         mkasm(u, "%%%s", ud_reg_tab[op->index - UD_R_AL]);
  64.                 }
  65.                 if (op->scale)
  66.                         mkasm(u, ",%d", op->scale);
  67.                 if (op->base || op->index)
  68.                         mkasm(u, ")");
  69.                 break;
  70.  
  71.         case UD_OP_IMM:
  72.                 switch (op->size) {
  73.                         case  8: mkasm(u, "$0x%x", op->lval.ubyte);    break;
  74.                         case 16: mkasm(u, "$0x%x", op->lval.uword);    break;
  75.                         case 32: mkasm(u, "$0x%lx", op->lval.udword);  break;
  76.                         case 64: mkasm(u, "$0x" FMT64 "x", op->lval.uqword); break;
  77.                         default: break;
  78.                 }
  79.                 break;
  80.  
  81.         case UD_OP_JIMM:
  82.                 switch (op->size) {
  83.                         case  8:
  84.                                 mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sbyte);
  85.                                 break;
  86.                         case 16:
  87.                                 mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sword);
  88.                                 break;
  89.                         case 32:
  90.                                 mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sdword);
  91.                                 break;
  92.                         default:break;
  93.                 }
  94.                 break;
  95.  
  96.         case UD_OP_PTR:
  97.                 switch (op->size) {
  98.                         case 32:
  99.                                 mkasm(u, "$0x%x, $0x%x", op->lval.ptr.seg,
  100.                                         op->lval.ptr.off & 0xFFFF);
  101.                                 break;
  102.                         case 48:
  103.                                 mkasm(u, "$0x%x, $0x%lx", op->lval.ptr.seg,
  104.                                         op->lval.ptr.off);
  105.                                 break;
  106.                 }
  107.                 break;
  108.                        
  109.         default: return;
  110.   }
  111. }
  112.  
  113. /* =============================================================================
  114.  * translates to AT&T syntax
  115.  * =============================================================================
  116.  */
  117. extern void
  118. ud_translate_att(struct ud *u)
  119. {
  120.   int size = 0;
  121.  
  122.   /* check if P_OSO prefix is used */
  123.   if (! P_OSO(u->itab_entry->prefix) && u->pfx_opr) {
  124.         switch (u->dis_mode) {
  125.                 case 16:
  126.                         mkasm(u, "o32 ");
  127.                         break;
  128.                 case 32:
  129.                 case 64:
  130.                         mkasm(u, "o16 ");
  131.                         break;
  132.         }
  133.   }
  134.  
  135.   /* check if P_ASO prefix was used */
  136.   if (! P_ASO(u->itab_entry->prefix) && u->pfx_adr) {
  137.         switch (u->dis_mode) {
  138.                 case 16:
  139.                         mkasm(u, "a32 ");
  140.                         break;
  141.                 case 32:
  142.                         mkasm(u, "a16 ");
  143.                         break;
  144.                 case 64:
  145.                         mkasm(u, "a32 ");
  146.                         break;
  147.         }
  148.   }
  149.  
  150.   if (u->pfx_lock)
  151.         mkasm(u,  "lock ");
  152.   if (u->pfx_rep)
  153.         mkasm(u,  "rep ");
  154.   if (u->pfx_repne)
  155.                 mkasm(u,  "repne ");
  156.  
  157.   /* special instructions */
  158.   switch (u->mnemonic) {
  159.         case UD_Iretf:
  160.                 mkasm(u, "lret ");
  161.                 break;
  162.         case UD_Idb:
  163.                 mkasm(u, ".byte 0x%x", u->operand[0].lval.ubyte);
  164.                 return;
  165.         case UD_Ijmp:
  166.         case UD_Icall:
  167.                 if (u->br_far) mkasm(u,  "l");
  168.                 mkasm(u, "%s", ud_lookup_mnemonic(u->mnemonic));
  169.                 break;
  170.         case UD_Ibound:
  171.         case UD_Ienter:
  172.                 if (u->operand[0].type != UD_NONE)
  173.                         gen_operand(u, &u->operand[0]);
  174.                 if (u->operand[1].type != UD_NONE) {
  175.                         mkasm(u, ",");
  176.                         gen_operand(u, &u->operand[1]);
  177.                 }
  178.                 return;
  179.         default:
  180.                 mkasm(u, "%s", ud_lookup_mnemonic(u->mnemonic));
  181.   }
  182.  
  183.   if (u->c1)
  184.         size = u->operand[0].size;
  185.   else if (u->c2)
  186.         size = u->operand[1].size;
  187.   else if (u->c3)
  188.         size = u->operand[2].size;
  189.  
  190.   if (size == 8)
  191.         mkasm(u, "b");
  192.   else if (size == 16)
  193.         mkasm(u, "w");
  194.   else if (size == 64)
  195.         mkasm(u, "q");
  196.  
  197.   mkasm(u, " ");
  198.  
  199.   if (u->operand[2].type != UD_NONE) {
  200.         gen_operand(u, &u->operand[2]);
  201.         mkasm(u, ", ");
  202.   }
  203.  
  204.   if (u->operand[1].type != UD_NONE) {
  205.         gen_operand(u, &u->operand[1]);
  206.         mkasm(u, ", ");
  207.   }
  208.  
  209.   if (u->operand[0].type != UD_NONE)
  210.         gen_operand(u, &u->operand[0]);
  211. }
  212.