2 * Copyright (C) 2014 Apple Inc. All Rights Reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "UnlinkedInstructionStream.h"
31 static void append8(unsigned char*& ptr
, unsigned char value
)
36 static void append32(unsigned char*& ptr
, unsigned value
)
38 if (!(value
& 0xffffffe0)) {
43 if ((value
& 0xffffffe0) == 0xffffffe0) {
44 *(ptr
++) = (Negative5Bit
<< 5) | (value
& 0x1f);
48 if ((value
& 0xffffffe0) == 0x40000000) {
49 *(ptr
++) = (ConstantRegister5Bit
<< 5) | (value
& 0x1f);
53 if (!(value
& 0xffffe000)) {
54 *(ptr
++) = (Positive13Bit
<< 5) | ((value
>> 8) & 0x1f);
55 *(ptr
++) = value
& 0xff;
59 if ((value
& 0xffffe000) == 0xffffe000) {
60 *(ptr
++) = (Negative13Bit
<< 5) | ((value
>> 8) & 0x1f);
61 *(ptr
++) = value
& 0xff;
65 if ((value
& 0xffffe000) == 0x40000000) {
66 *(ptr
++) = (ConstantRegister13Bit
<< 5) | ((value
>> 8) & 0x1f);
67 *(ptr
++) = value
& 0xff;
71 *(ptr
++) = Full32Bit
<< 5;
72 *(ptr
++) = value
& 0xff;
73 *(ptr
++) = (value
>> 8) & 0xff;
74 *(ptr
++) = (value
>> 16) & 0xff;
75 *(ptr
++) = (value
>> 24) & 0xff;
78 UnlinkedInstructionStream::UnlinkedInstructionStream(const Vector
<UnlinkedInstruction
, 0, UnsafeVectorOverflow
>& instructions
)
79 : m_instructionCount(instructions
.size())
81 Vector
<unsigned char> buffer
;
83 // Reserve enough space up front so we never have to reallocate when appending.
84 buffer
.resizeToFit(m_instructionCount
* 5);
85 unsigned char* ptr
= buffer
.data();
87 const UnlinkedInstruction
* instructionsData
= instructions
.data();
88 for (unsigned i
= 0; i
< m_instructionCount
;) {
89 const UnlinkedInstruction
* pc
= &instructionsData
[i
];
90 OpcodeID opcode
= pc
[0].u
.opcode
;
93 unsigned opLength
= opcodeLength(opcode
);
95 for (unsigned j
= 1; j
< opLength
; ++j
)
96 append32(ptr
, pc
[j
].u
.index
);
101 buffer
.shrink(ptr
- buffer
.data());
102 m_data
= RefCountedArray
<unsigned char>(buffer
);
106 const RefCountedArray
<UnlinkedInstruction
>& UnlinkedInstructionStream::unpackForDebugging() const
108 if (!m_unpackedInstructionsForDebugging
.size()) {
109 m_unpackedInstructionsForDebugging
= RefCountedArray
<UnlinkedInstruction
>(m_instructionCount
);
111 Reader
instructionReader(*this);
112 for (unsigned i
= 0; !instructionReader
.atEnd(); ) {
113 const UnlinkedInstruction
* pc
= instructionReader
.next();
114 unsigned opLength
= opcodeLength(pc
[0].u
.opcode
);
115 for (unsigned j
= 0; j
< opLength
; ++j
)
116 m_unpackedInstructionsForDebugging
[i
++] = pc
[j
];
120 return m_unpackedInstructionsForDebugging
;