提交 7b8a354d 编写于 作者: P Peter Maydell

Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20160111-1' into staging

target-arm queue:
 * i.MX: move i.MX31 CCM object to register array
 * xilinx_axidma: remove dead code
 * disas/libvixl: Update to upstream VIXL 1.12
 * virt: Support legacy -nic command line syntax

# gpg: Signature made Mon 11 Jan 2016 16:05:58 GMT using RSA key ID 14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>"
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>"

* remotes/pmaydell/tags/pull-target-arm-20160111-1:
  hw/arm/virt: Support legacy -nic command line syntax
  disas/libvixl: Update to upstream VIXL 1.12
  hw/dma/xilinx_axidma: remove dead code
  i.MX: move i.MX31 CCM object to register array
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
......@@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "a64/disasm-a64.h"
#include "vixl/a64/disasm-a64.h"
extern "C" {
#include "disas/bfd.h"
......
libvixl_OBJS = utils.o \
a64/instructions-a64.o \
a64/decoder-a64.o \
a64/disasm-a64.o
libvixl_OBJS = vixl/utils.o \
vixl/compiler-intrinsics.o \
vixl/a64/instructions-a64.o \
vixl/a64/decoder-a64.o \
vixl/a64/disasm-a64.o
$(addprefix $(obj)/,$(libvixl_OBJS)): QEMU_CFLAGS := -I$(SRC_PATH)/disas/libvixl $(QEMU_CFLAGS)
......
......@@ -2,11 +2,10 @@
The code in this directory is a subset of libvixl:
https://github.com/armvixl/vixl
(specifically, it is the set of files needed for disassembly only,
taken from libvixl 1.7).
taken from libvixl 1.12).
Bugfixes should preferably be sent upstream initially.
The disassembler does not currently support the entire A64 instruction
set. Notably:
* No Advanced SIMD support.
* Limited support for system instructions.
* A few miscellaneous integer and floating point instructions are missing.
// Copyright 2013, ARM Limited
// Copyright 2014, ARM Limited
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
......@@ -27,8 +27,8 @@
#ifndef VIXL_CPU_A64_H
#define VIXL_CPU_A64_H
#include "globals.h"
#include "instructions-a64.h"
#include "vixl/globals.h"
#include "vixl/a64/instructions-a64.h"
namespace vixl {
......
// Copyright 2013, ARM Limited
// Copyright 2014, ARM Limited
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
......@@ -24,9 +24,9 @@
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "globals.h"
#include "utils.h"
#include "a64/decoder-a64.h"
#include "vixl/globals.h"
#include "vixl/utils.h"
#include "vixl/a64/decoder-a64.h"
namespace vixl {
......@@ -271,6 +271,11 @@ void Decoder::DecodeLoadStore(const Instruction* instr) {
(instr->Bits(27, 24) == 0x9) ||
(instr->Bits(27, 24) == 0xC) ||
(instr->Bits(27, 24) == 0xD) );
// TODO(all): rearrange the tree to integrate this branch.
if ((instr->Bit(28) == 0) && (instr->Bit(29) == 0) && (instr->Bit(26) == 1)) {
DecodeNEONLoadStore(instr);
return;
}
if (instr->Bit(24) == 0) {
if (instr->Bit(28) == 0) {
......@@ -278,7 +283,7 @@ void Decoder::DecodeLoadStore(const Instruction* instr) {
if (instr->Bit(26) == 0) {
VisitLoadStoreExclusive(instr);
} else {
DecodeAdvSIMDLoadStore(instr);
VIXL_UNREACHABLE();
}
} else {
if ((instr->Bits(31, 30) == 0x3) ||
......@@ -483,6 +488,7 @@ void Decoder::DecodeDataProcessing(const Instruction* instr) {
case 6: {
if (instr->Bit(29) == 0x1) {
VisitUnallocated(instr);
VIXL_FALLTHROUGH();
} else {
if (instr->Bit(30) == 0) {
if ((instr->Bit(15) == 0x1) ||
......@@ -556,18 +562,15 @@ void Decoder::DecodeDataProcessing(const Instruction* instr) {
void Decoder::DecodeFP(const Instruction* instr) {
VIXL_ASSERT((instr->Bits(27, 24) == 0xE) ||
(instr->Bits(27, 24) == 0xF));
if (instr->Bit(28) == 0) {
DecodeAdvSIMDDataProcessing(instr);
DecodeNEONVectorDataProcessing(instr);
} else {
if (instr->Bit(29) == 1) {
if (instr->Bits(31, 30) == 0x3) {
VisitUnallocated(instr);
} else if (instr->Bits(31, 30) == 0x1) {
DecodeNEONScalarDataProcessing(instr);
} else {
if (instr->Bits(31, 30) == 0x3) {
VisitUnallocated(instr);
} else if (instr->Bits(31, 30) == 0x1) {
DecodeAdvSIMDDataProcessing(instr);
} else {
if (instr->Bit(29) == 0) {
if (instr->Bit(24) == 0) {
if (instr->Bit(21) == 0) {
if ((instr->Bit(23) == 1) ||
......@@ -674,23 +677,190 @@ void Decoder::DecodeFP(const Instruction* instr) {
VisitFPDataProcessing3Source(instr);
}
}
} else {
VisitUnallocated(instr);
}
}
}
}
void Decoder::DecodeAdvSIMDLoadStore(const Instruction* instr) {
// TODO: Implement Advanced SIMD load/store instruction decode.
void Decoder::DecodeNEONLoadStore(const Instruction* instr) {
VIXL_ASSERT(instr->Bits(29, 25) == 0x6);
VisitUnimplemented(instr);
if (instr->Bit(31) == 0) {
if ((instr->Bit(24) == 0) && (instr->Bit(21) == 1)) {
VisitUnallocated(instr);
return;
}
if (instr->Bit(23) == 0) {
if (instr->Bits(20, 16) == 0) {
if (instr->Bit(24) == 0) {
VisitNEONLoadStoreMultiStruct(instr);
} else {
VisitNEONLoadStoreSingleStruct(instr);
}
} else {
VisitUnallocated(instr);
}
} else {
if (instr->Bit(24) == 0) {
VisitNEONLoadStoreMultiStructPostIndex(instr);
} else {
VisitNEONLoadStoreSingleStructPostIndex(instr);
}
}
} else {
VisitUnallocated(instr);
}
}
void Decoder::DecodeNEONVectorDataProcessing(const Instruction* instr) {
VIXL_ASSERT(instr->Bits(28, 25) == 0x7);
if (instr->Bit(31) == 0) {
if (instr->Bit(24) == 0) {
if (instr->Bit(21) == 0) {
if (instr->Bit(15) == 0) {
if (instr->Bit(10) == 0) {
if (instr->Bit(29) == 0) {
if (instr->Bit(11) == 0) {
VisitNEONTable(instr);
} else {
VisitNEONPerm(instr);
}
} else {
VisitNEONExtract(instr);
}
} else {
if (instr->Bits(23, 22) == 0) {
VisitNEONCopy(instr);
} else {
VisitUnallocated(instr);
}
}
} else {
VisitUnallocated(instr);
}
} else {
if (instr->Bit(10) == 0) {
if (instr->Bit(11) == 0) {
VisitNEON3Different(instr);
} else {
if (instr->Bits(18, 17) == 0) {
if (instr->Bit(20) == 0) {
if (instr->Bit(19) == 0) {
VisitNEON2RegMisc(instr);
} else {
if (instr->Bits(30, 29) == 0x2) {
VisitCryptoAES(instr);
} else {
VisitUnallocated(instr);
}
}
} else {
if (instr->Bit(19) == 0) {
VisitNEONAcrossLanes(instr);
} else {
VisitUnallocated(instr);
}
}
} else {
VisitUnallocated(instr);
}
}
} else {
VisitNEON3Same(instr);
}
}
} else {
if (instr->Bit(10) == 0) {
VisitNEONByIndexedElement(instr);
} else {
if (instr->Bit(23) == 0) {
if (instr->Bits(22, 19) == 0) {
VisitNEONModifiedImmediate(instr);
} else {
VisitNEONShiftImmediate(instr);
}
} else {
VisitUnallocated(instr);
}
}
}
} else {
VisitUnallocated(instr);
}
}
void Decoder::DecodeAdvSIMDDataProcessing(const Instruction* instr) {
// TODO: Implement Advanced SIMD data processing instruction decode.
VIXL_ASSERT(instr->Bits(27, 25) == 0x7);
VisitUnimplemented(instr);
void Decoder::DecodeNEONScalarDataProcessing(const Instruction* instr) {
VIXL_ASSERT(instr->Bits(28, 25) == 0xF);
if (instr->Bit(24) == 0) {
if (instr->Bit(21) == 0) {
if (instr->Bit(15) == 0) {
if (instr->Bit(10) == 0) {
if (instr->Bit(29) == 0) {
if (instr->Bit(11) == 0) {
VisitCrypto3RegSHA(instr);
} else {
VisitUnallocated(instr);
}
} else {
VisitUnallocated(instr);
}
} else {
if (instr->Bits(23, 22) == 0) {
VisitNEONScalarCopy(instr);
} else {
VisitUnallocated(instr);
}
}
} else {
VisitUnallocated(instr);
}
} else {
if (instr->Bit(10) == 0) {
if (instr->Bit(11) == 0) {
VisitNEONScalar3Diff(instr);
} else {
if (instr->Bits(18, 17) == 0) {
if (instr->Bit(20) == 0) {
if (instr->Bit(19) == 0) {
VisitNEONScalar2RegMisc(instr);
} else {
if (instr->Bit(29) == 0) {
VisitCrypto2RegSHA(instr);
} else {
VisitUnallocated(instr);
}
}
} else {
if (instr->Bit(19) == 0) {
VisitNEONScalarPairwise(instr);
} else {
VisitUnallocated(instr);
}
}
} else {
VisitUnallocated(instr);
}
}
} else {
VisitNEONScalar3Same(instr);
}
}
} else {
if (instr->Bit(10) == 0) {
VisitNEONScalarByIndexedElement(instr);
} else {
if (instr->Bit(23) == 0) {
VisitNEONScalarShiftImmediate(instr);
} else {
VisitUnallocated(instr);
}
}
}
}
......
// Copyright 2013, ARM Limited
// Copyright 2014, ARM Limited
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
......@@ -29,13 +29,13 @@
#include <list>
#include "globals.h"
#include "a64/instructions-a64.h"
#include "vixl/globals.h"
#include "vixl/a64/instructions-a64.h"
// List macro containing all visitors needed by the decoder class.
#define VISITOR_LIST(V) \
#define VISITOR_LIST_THAT_RETURN(V) \
V(PCRelAddressing) \
V(AddSubImmediate) \
V(LogicalImmediate) \
......@@ -79,8 +79,39 @@
V(FPDataProcessing3Source) \
V(FPIntegerConvert) \
V(FPFixedPointConvert) \
V(Unallocated) \
V(Unimplemented)
V(Crypto2RegSHA) \
V(Crypto3RegSHA) \
V(CryptoAES) \
V(NEON2RegMisc) \
V(NEON3Different) \
V(NEON3Same) \
V(NEONAcrossLanes) \
V(NEONByIndexedElement) \
V(NEONCopy) \
V(NEONExtract) \
V(NEONLoadStoreMultiStruct) \
V(NEONLoadStoreMultiStructPostIndex) \
V(NEONLoadStoreSingleStruct) \
V(NEONLoadStoreSingleStructPostIndex) \
V(NEONModifiedImmediate) \
V(NEONScalar2RegMisc) \
V(NEONScalar3Diff) \
V(NEONScalar3Same) \
V(NEONScalarByIndexedElement) \
V(NEONScalarCopy) \
V(NEONScalarPairwise) \
V(NEONScalarShiftImmediate) \
V(NEONShiftImmediate) \
V(NEONTable) \
V(NEONPerm) \
#define VISITOR_LIST_THAT_DONT_RETURN(V) \
V(Unallocated) \
V(Unimplemented) \
#define VISITOR_LIST(V) \
VISITOR_LIST_THAT_RETURN(V) \
VISITOR_LIST_THAT_DONT_RETURN(V) \
namespace vixl {
......@@ -222,12 +253,17 @@ class Decoder {
// Decode the Advanced SIMD (NEON) load/store part of the instruction tree,
// and call the corresponding visitors.
// On entry, instruction bits 29:25 = 0x6.
void DecodeAdvSIMDLoadStore(const Instruction* instr);
void DecodeNEONLoadStore(const Instruction* instr);
// Decode the Advanced SIMD (NEON) data processing part of the instruction
// tree, and call the corresponding visitors.
// On entry, instruction bits 27:25 = 0x7.
void DecodeAdvSIMDDataProcessing(const Instruction* instr);
// Decode the Advanced SIMD (NEON) vector data processing part of the
// instruction tree, and call the corresponding visitors.
// On entry, instruction bits 28:25 = 0x7.
void DecodeNEONVectorDataProcessing(const Instruction* instr);
// Decode the Advanced SIMD (NEON) scalar data processing part of the
// instruction tree, and call the corresponding visitors.
// On entry, instruction bits 28:25 = 0xF.
void DecodeNEONScalarDataProcessing(const Instruction* instr);
private:
// Visitors are registered in a list.
......
// Copyright 2013, ARM Limited
// Copyright 2015, ARM Limited
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
......@@ -27,11 +27,11 @@
#ifndef VIXL_A64_DISASM_A64_H
#define VIXL_A64_DISASM_A64_H
#include "globals.h"
#include "utils.h"
#include "instructions-a64.h"
#include "decoder-a64.h"
#include "assembler-a64.h"
#include "vixl/globals.h"
#include "vixl/utils.h"
#include "vixl/a64/instructions-a64.h"
#include "vixl/a64/decoder-a64.h"
#include "vixl/a64/assembler-a64.h"
namespace vixl {
......@@ -55,6 +55,7 @@ class Disassembler: public DecoderVisitor {
// customize the disassembly output.
// Prints the name of a register.
// TODO: This currently doesn't allow renaming of V registers.
virtual void AppendRegisterNameToOutput(const Instruction* instr,
const CPURegister& reg);
......@@ -122,7 +123,8 @@ class Disassembler: public DecoderVisitor {
int SubstituteLSRegOffsetField(const Instruction* instr, const char* format);
int SubstitutePrefetchField(const Instruction* instr, const char* format);
int SubstituteBarrierField(const Instruction* instr, const char* format);
int SubstituteSysOpField(const Instruction* instr, const char* format);
int SubstituteCrField(const Instruction* instr, const char* format);
bool RdIsZROrSP(const Instruction* instr) const {
return (instr->Rd() == kZeroRegCode);
}
......@@ -163,7 +165,6 @@ class Disassembler: public DecoderVisitor {
class PrintDisassembler: public Disassembler {
public:
explicit PrintDisassembler(FILE* stream) : stream_(stream) { }
virtual ~PrintDisassembler() { }
protected:
virtual void ProcessOutput(const Instruction* instr);
......
......@@ -28,7 +28,7 @@
#define VIXL_CODE_BUFFER_H
#include <string.h>
#include "globals.h"
#include "vixl/globals.h"
namespace vixl {
......
// Copyright 2013, ARM Limited
// Copyright 2015, ARM Limited
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
......@@ -24,53 +24,13 @@
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "utils.h"
#include <stdio.h>
#include "compiler-intrinsics.h"
namespace vixl {
uint32_t float_to_rawbits(float value) {
uint32_t bits = 0;
memcpy(&bits, &value, 4);
return bits;
}
uint64_t double_to_rawbits(double value) {
uint64_t bits = 0;
memcpy(&bits, &value, 8);
return bits;
}
float rawbits_to_float(uint32_t bits) {
float value = 0.0;
memcpy(&value, &bits, 4);
return value;
}
double rawbits_to_double(uint64_t bits) {
double value = 0.0;
memcpy(&value, &bits, 8);
return value;
}
int CountLeadingZeros(uint64_t value, int width) {
VIXL_ASSERT((width == 32) || (width == 64));
int count = 0;
uint64_t bit_test = UINT64_C(1) << (width - 1);
while ((count < width) && ((bit_test & value) == 0)) {
count++;
bit_test >>= 1;
}
return count;
}
int CountLeadingSignBits(int64_t value, int width) {
VIXL_ASSERT((width == 32) || (width == 64));
int CountLeadingSignBitsFallBack(int64_t value, int width) {
VIXL_ASSERT(IsPowerOf2(width) && (width <= 64));
if (value >= 0) {
return CountLeadingZeros(value, width) - 1;
} else {
......@@ -79,23 +39,46 @@ int CountLeadingSignBits(int64_t value, int width) {
}
int CountTrailingZeros(uint64_t value, int width) {
VIXL_ASSERT((width == 32) || (width == 64));
int CountLeadingZerosFallBack(uint64_t value, int width) {
VIXL_ASSERT(IsPowerOf2(width) && (width <= 64));
if (value == 0) {
return width;
}
int count = 0;
while ((count < width) && (((value >> count) & 1) == 0)) {
count++;
value = value << (64 - width);
if ((value & UINT64_C(0xffffffff00000000)) == 0) {
count += 32;
value = value << 32;
}
if ((value & UINT64_C(0xffff000000000000)) == 0) {
count += 16;
value = value << 16;
}
if ((value & UINT64_C(0xff00000000000000)) == 0) {
count += 8;
value = value << 8;
}
if ((value & UINT64_C(0xf000000000000000)) == 0) {
count += 4;
value = value << 4;
}
if ((value & UINT64_C(0xc000000000000000)) == 0) {
count += 2;
value = value << 2;
}
if ((value & UINT64_C(0x8000000000000000)) == 0) {
count += 1;
}
count += (value == 0);
return count;
}
int CountSetBits(uint64_t value, int width) {
// TODO: Other widths could be added here, as the implementation already
// supports them.
VIXL_ASSERT((width == 32) || (width == 64));
int CountSetBitsFallBack(uint64_t value, int width) {
VIXL_ASSERT(IsPowerOf2(width) && (width <= 64));
// Mask out unused bits to ensure that they are not counted.
value &= (UINT64_C(0xffffffffffffffff) >> (64-width));
value &= (UINT64_C(0xffffffffffffffff) >> (64 - width));
// Add up the set bits.
// The algorithm works by adding pairs of bit fields together iteratively,
......@@ -122,30 +105,40 @@ int CountSetBits(uint64_t value, int width) {
value = ((value >> shift) & kMasks[i]) + (value & kMasks[i]);
}
return value;
}
uint64_t LowestSetBit(uint64_t value) {
return value & -value;
}
bool IsPowerOf2(int64_t value) {
return (value != 0) && ((value & (value - 1)) == 0);
return static_cast<int>(value);
}
unsigned CountClearHalfWords(uint64_t imm, unsigned reg_size) {
VIXL_ASSERT((reg_size % 8) == 0);
int CountTrailingZerosFallBack(uint64_t value, int width) {
VIXL_ASSERT(IsPowerOf2(width) && (width <= 64));
int count = 0;
for (unsigned i = 0; i < (reg_size / 16); i++) {
if ((imm & 0xffff) == 0) {
count++;
}
imm >>= 16;
value = value << (64 - width);
if ((value & UINT64_C(0xffffffff)) == 0) {
count += 32;
value = value >> 32;
}
return count;
if ((value & 0xffff) == 0) {
count += 16;
value = value >> 16;
}
if ((value & 0xff) == 0) {
count += 8;
value = value >> 8;
}
if ((value & 0xf) == 0) {
count += 4;
value = value >> 4;
}
if ((value & 0x3) == 0) {
count += 2;
value = value >> 2;
}
if ((value & 0x1) == 0) {
count += 1;
}
count += (value == 0);
return count - (64 - width);
}
} // namespace vixl
此差异已折叠。
此差异已折叠。
// Copyright 2013, ARM Limited
// Copyright 2014, ARM Limited
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
......
此差异已折叠。
......@@ -808,6 +808,7 @@ static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic,
DeviceState *dev;
char *nodename;
int i;
PCIHostState *pci;
dev = qdev_create(NULL, TYPE_GPEX_HOST);
qdev_init_nofail(dev);
......@@ -847,6 +848,19 @@ static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic,
sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
}
pci = PCI_HOST_BRIDGE(dev);
if (pci->bus) {
for (i = 0; i < nb_nics; i++) {
NICInfo *nd = &nd_table[i];
if (!nd->model) {
nd->model = g_strdup("virtio");
}
pci_nic_init_nofail(nd, pci->bus, nd->model, NULL);
}
}
nodename = g_strdup_printf("/pcie@%" PRIx64, base);
qemu_fdt_add_subnode(vbi->fdt, nodename);
qemu_fdt_setprop_string(vbi->fdt, nodename,
......
......@@ -177,16 +177,6 @@ static inline int streamid_from_addr(hwaddr addr)
return sid;
}
#ifdef DEBUG_ENET
static void stream_desc_show(struct SDesc *d)
{
qemu_log("buffer_addr = " PRIx64 "\n", d->buffer_address);
qemu_log("nxtdesc = " PRIx64 "\n", d->nxtdesc);
qemu_log("control = %x\n", d->control);
qemu_log("status = %x\n", d->status);
}
#endif
static void stream_desc_load(struct Stream *s, hwaddr addr)
{
struct SDesc *d = &s->desc;
......
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册