10ae96273SGreg Clayton //===-- Baton.cpp -----------------------------------------------*- C++ -*-===//
20ae96273SGreg Clayton //
30ae96273SGreg Clayton //                     The LLVM Compiler Infrastructure
40ae96273SGreg Clayton //
50ae96273SGreg Clayton // This file is distributed under the University of Illinois Open Source
60ae96273SGreg Clayton // License. See LICENSE.TXT for details.
70ae96273SGreg Clayton //
80ae96273SGreg Clayton //===----------------------------------------------------------------------===//
90ae96273SGreg Clayton 
100ae96273SGreg Clayton #include "lldb/Core/Opcode.h"
110ae96273SGreg Clayton 
120ae96273SGreg Clayton // C Includes
130ae96273SGreg Clayton // C++ Includes
140ae96273SGreg Clayton // Other libraries and framework includes
150ae96273SGreg Clayton // Project includes
16*d1411e1aSGreg Clayton #include "lldb/Core/DataBufferHeap.h"
17*d1411e1aSGreg Clayton #include "lldb/Core/DataExtractor.h"
181080edbcSGreg Clayton #include "lldb/Core/Stream.h"
198f7180b1SGreg Clayton #include "lldb/Host/Endian.h"
200ae96273SGreg Clayton 
210ae96273SGreg Clayton using namespace lldb;
220ae96273SGreg Clayton using namespace lldb_private;
231080edbcSGreg Clayton 
241080edbcSGreg Clayton 
251080edbcSGreg Clayton int
261080edbcSGreg Clayton Opcode::Dump (Stream *s, uint32_t min_byte_width)
271080edbcSGreg Clayton {
281080edbcSGreg Clayton     int bytes_written = 0;
291080edbcSGreg Clayton     switch (m_type)
301080edbcSGreg Clayton     {
311080edbcSGreg Clayton     case Opcode::eTypeInvalid:
321080edbcSGreg Clayton         bytes_written = s->PutCString ("<invalid>");
331080edbcSGreg Clayton         break;
341080edbcSGreg Clayton     case Opcode::eType8:
351080edbcSGreg Clayton         bytes_written = s->Printf ("0x%2.2x", m_data.inst8);
361080edbcSGreg Clayton         break;
371080edbcSGreg Clayton     case Opcode::eType16:
381080edbcSGreg Clayton         bytes_written = s->Printf ("0x%4.4x", m_data.inst16);
391080edbcSGreg Clayton         break;
401080edbcSGreg Clayton 
411080edbcSGreg Clayton     case Opcode::eType32:
421080edbcSGreg Clayton         bytes_written = s->Printf ("0x%8.8x", m_data.inst32);
431080edbcSGreg Clayton         break;
441080edbcSGreg Clayton 
451080edbcSGreg Clayton     case Opcode::eType64:
461080edbcSGreg Clayton         bytes_written = s->Printf ("0x%16.16llx", m_data.inst64);
471080edbcSGreg Clayton         break;
481080edbcSGreg Clayton 
491080edbcSGreg Clayton     case Opcode::eTypeBytes:
501080edbcSGreg Clayton         {
511080edbcSGreg Clayton             for (uint32_t i=0; i<m_data.inst.length; ++i)
521080edbcSGreg Clayton             {
531080edbcSGreg Clayton                 if (i > 0)
54357132ebSGreg Clayton                     bytes_written += s->PutChar (' ');
551080edbcSGreg Clayton                 bytes_written += s->Printf ("%2.2x", m_data.inst.bytes[i]);
561080edbcSGreg Clayton             }
571080edbcSGreg Clayton         }
581080edbcSGreg Clayton         break;
591080edbcSGreg Clayton     }
601080edbcSGreg Clayton 
611080edbcSGreg Clayton     // Add spaces to make sure bytes dispay comes out even in case opcodes
621080edbcSGreg Clayton     // aren't all the same size
631080edbcSGreg Clayton     if (bytes_written < min_byte_width)
641080edbcSGreg Clayton         bytes_written = s->Printf ("%*s", min_byte_width - bytes_written, "");
651080edbcSGreg Clayton     return bytes_written;
661080edbcSGreg Clayton }
671080edbcSGreg Clayton 
688f7180b1SGreg Clayton lldb::ByteOrder
698f7180b1SGreg Clayton Opcode::GetDataByteOrder () const
708f7180b1SGreg Clayton {
718f7180b1SGreg Clayton     switch (m_type)
728f7180b1SGreg Clayton     {
738f7180b1SGreg Clayton         case Opcode::eTypeInvalid: break;
748f7180b1SGreg Clayton         case Opcode::eType8:
758f7180b1SGreg Clayton         case Opcode::eType16:
768f7180b1SGreg Clayton         case Opcode::eType32:
778f7180b1SGreg Clayton         case Opcode::eType64:    return lldb::endian::InlHostByteOrder();
788f7180b1SGreg Clayton         case Opcode::eTypeBytes:
798f7180b1SGreg Clayton             break;
808f7180b1SGreg Clayton     }
818f7180b1SGreg Clayton     return eByteOrderInvalid;
828f7180b1SGreg Clayton }
838f7180b1SGreg Clayton 
84*d1411e1aSGreg Clayton uint32_t
85*d1411e1aSGreg Clayton Opcode::GetData (DataExtractor &data) const
86*d1411e1aSGreg Clayton {
87*d1411e1aSGreg Clayton     uint32_t byte_size = GetByteSize ();
88*d1411e1aSGreg Clayton     DataBufferSP buffer_sp;
89*d1411e1aSGreg Clayton     if (byte_size > 0)
90*d1411e1aSGreg Clayton     {
91*d1411e1aSGreg Clayton         switch (m_type)
92*d1411e1aSGreg Clayton         {
93*d1411e1aSGreg Clayton             case Opcode::eTypeInvalid:
94*d1411e1aSGreg Clayton                 break;
95*d1411e1aSGreg Clayton 
96*d1411e1aSGreg Clayton             case Opcode::eType8:    buffer_sp.reset (new DataBufferHeap (&m_data.inst8,  byte_size)); break;
97*d1411e1aSGreg Clayton             case Opcode::eType16:   buffer_sp.reset (new DataBufferHeap (&m_data.inst16, byte_size)); break;
98*d1411e1aSGreg Clayton             case Opcode::eType32:   buffer_sp.reset (new DataBufferHeap (&m_data.inst32, byte_size)); break;
99*d1411e1aSGreg Clayton             case Opcode::eType64:   buffer_sp.reset (new DataBufferHeap (&m_data.inst64, byte_size)); break;
100*d1411e1aSGreg Clayton             case Opcode::eTypeBytes:buffer_sp.reset (new DataBufferHeap (GetOpcodeBytes(), byte_size)); break;
101*d1411e1aSGreg Clayton                 break;
102*d1411e1aSGreg Clayton         }
103*d1411e1aSGreg Clayton     }
104*d1411e1aSGreg Clayton 
105*d1411e1aSGreg Clayton     if (buffer_sp)
106*d1411e1aSGreg Clayton     {
107*d1411e1aSGreg Clayton         data.SetByteOrder(GetDataByteOrder());
108*d1411e1aSGreg Clayton         data.SetData (buffer_sp);
109*d1411e1aSGreg Clayton         return byte_size;
110*d1411e1aSGreg Clayton     }
111*d1411e1aSGreg Clayton     data.Clear();
112*d1411e1aSGreg Clayton     return 0;
113*d1411e1aSGreg Clayton }
114*d1411e1aSGreg Clayton 
115*d1411e1aSGreg Clayton 
116*d1411e1aSGreg Clayton 
117