From: Bradley Smith Date: Tue, 30 Sep 2014 16:31:40 +0000 (+0000) Subject: Extend C disassembler API to allow specifying target features X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=95b3e168c5b96225b35f21f73db27996492ecace;p=oota-llvm.git Extend C disassembler API to allow specifying target features git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218682 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm-c/Disassembler.h b/include/llvm-c/Disassembler.h index 8f31150ad91..d6cbe31cbb4 100644 --- a/include/llvm-c/Disassembler.h +++ b/include/llvm-c/Disassembler.h @@ -174,8 +174,8 @@ extern "C" { * by passing a block of information in the DisInfo parameter and specifying the * TagType and callback functions as described above. These can all be passed * as NULL. If successful, this returns a disassembler context. If not, it - * returns NULL. This function is equivalent to calling LLVMCreateDisasmCPU() - * with an empty CPU name. + * returns NULL. This function is equivalent to calling + * LLVMCreateDisasmCPUFeatures() with an empty CPU name and feature set. */ LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo, int TagType, LLVMOpInfoCallback GetOpInfo, @@ -186,13 +186,27 @@ LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo, * disassembly is supported by passing a block of information in the DisInfo * parameter and specifying the TagType and callback functions as described * above. These can all be passed * as NULL. If successful, this returns a - * disassembler context. If not, it returns NULL. + * disassembler context. If not, it returns NULL. This function is equivalent + * to calling LLVMCreateDisasmCPUFeatures() with an empty feature set. */ LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU, void *DisInfo, int TagType, LLVMOpInfoCallback GetOpInfo, LLVMSymbolLookupCallback SymbolLookUp); +/** + * Create a disassembler for the TripleName, a specific CPU and specific feature + * string. Symbolic disassembly is supported by passing a block of information + * in the DisInfo parameter and specifying the TagType and callback functions as + * described above. These can all be passed * as NULL. If successful, this + * returns a disassembler context. If not, it returns NULL. + */ +LLVMDisasmContextRef +LLVMCreateDisasmCPUFeatures(const char *Triple, const char *CPU, + const char *Features, void *DisInfo, int TagType, + LLVMOpInfoCallback GetOpInfo, + LLVMSymbolLookupCallback SymbolLookUp); + /** * Set the disassembler's options. Returns 1 if it can set the Options and 0 * otherwise. diff --git a/lib/MC/MCDisassembler/Disassembler.cpp b/lib/MC/MCDisassembler/Disassembler.cpp index 0b0f9240793..321b1c173a5 100644 --- a/lib/MC/MCDisassembler/Disassembler.cpp +++ b/lib/MC/MCDisassembler/Disassembler.cpp @@ -33,10 +33,11 @@ using namespace llvm; // functions can all be passed as NULL. If successful, this returns a // disassembler context. If not, it returns NULL. // -LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU, - void *DisInfo, int TagType, - LLVMOpInfoCallback GetOpInfo, - LLVMSymbolLookupCallback SymbolLookUp){ +LLVMDisasmContextRef +LLVMCreateDisasmCPUFeatures(const char *Triple, const char *CPU, + const char *Features, void *DisInfo, int TagType, + LLVMOpInfoCallback GetOpInfo, + LLVMSymbolLookupCallback SymbolLookUp) { // Get the target. std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error); @@ -56,11 +57,8 @@ LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU, if (!MII) return nullptr; - // Package up features to be passed to target/subtarget - std::string FeaturesStr; - const MCSubtargetInfo *STI = TheTarget->createMCSubtargetInfo(Triple, CPU, - FeaturesStr); + Features); if (!STI) return nullptr; @@ -101,11 +99,19 @@ LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU, return DC; } +LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU, + void *DisInfo, int TagType, + LLVMOpInfoCallback GetOpInfo, + LLVMSymbolLookupCallback SymbolLookUp){ + return LLVMCreateDisasmCPUFeatures(Triple, CPU, "", DisInfo, TagType, + GetOpInfo, SymbolLookUp); +} + LLVMDisasmContextRef LLVMCreateDisasm(const char *Triple, void *DisInfo, int TagType, LLVMOpInfoCallback GetOpInfo, LLVMSymbolLookupCallback SymbolLookUp) { - return LLVMCreateDisasmCPU(Triple, "", DisInfo, TagType, GetOpInfo, - SymbolLookUp); + return LLVMCreateDisasmCPUFeatures(Triple, "", "", DisInfo, TagType, + GetOpInfo, SymbolLookUp); } // diff --git a/test/Bindings/llvm-c/disassemble.test b/test/Bindings/llvm-c/disassemble.test index 201e914587d..bb7a9a01ab9 100644 --- a/test/Bindings/llvm-c/disassemble.test +++ b/test/Bindings/llvm-c/disassemble.test @@ -1,15 +1,27 @@ ; RUN: llvm-c-test --disassemble < %s | FileCheck %s +armv8-linux-gnu +crypto 02 00 81 e0 02 03 b0 f3 +;CHECK: triple: armv8-linux-gnu, features: +crypto +;CHECK: 02 00 81 e0 add r0, r1, r2 +;CHECK: 02 03 b0 f3 aese.8 q0, q1 -arm-linux-android 44 26 1f e5 0c 10 4b e2 02 20 81 e0 -;CHECK: triple: arm-linux-android +armv8-linux-gnu -crypto 02 00 81 e0 02 03 b0 f3 +;CHECK: triple: armv8-linux-gnu, features: -crypto +;CHECK: 02 00 81 e0 add r0, r1, r2 +;CHECK: 02 ??? +;CHECK: 03 ??? +;CHECK: b0 ??? +;CHECK: f3 ??? + +arm-linux-android NULL 44 26 1f e5 0c 10 4b e2 02 20 81 e0 +;CHECK: triple: arm-linux-android, features: NULL ;CHECK: ldr r2, [pc, #-1604] ;CHECK: sub r1, r11, #12 ;CHECK: 02 20 81 e0 ;CHECK: add r2, r1, r2 -x86_64-linux-unknown 48 83 c4 38 5b 5d 41 5c 41 5d 41 5e 41 5f c3 -;CHECK: triple: x86_64-linux-unknown +x86_64-linux-unknown NULL 48 83 c4 38 5b 5d 41 5c 41 5d 41 5e 41 5f c3 +;CHECK: triple: x86_64-linux-unknown, features: NULL ;CHECK: addq $56, %rsp ;CHECK: popq %rbx ;CHECK: popq %rbp @@ -19,11 +31,13 @@ x86_64-linux-unknown 48 83 c4 38 5b 5d 41 5c 41 5d 41 5e 41 5f c3 ;CHECK: popq %r15 ;CHECK: ret -i686-apple-darwin 0f b7 4c 24 0a e8 29 ce ff ff +i686-apple-darwin NULL 0f b7 4c 24 0a e8 29 ce ff ff +;CHECK: triple: i686-apple-darwin, features: NULL ;CHECK: movzwl 10(%esp), %ecx ;CHECK: calll -12759 -i686-linux-unknown dd 44 24 04 d9 e1 c3 +i686-linux-unknown NULL dd 44 24 04 d9 e1 c3 +;CHECK: triple: i686-linux-unknown, features: NULL ;CHECK: fldl 4(%esp) ;CHECK: fabs ;CHECK: ret diff --git a/tools/llvm-c-test/disassemble.c b/tools/llvm-c-test/disassemble.c index eb40bf3d446..05a9218d014 100644 --- a/tools/llvm-c-test/disassemble.c +++ b/tools/llvm-c-test/disassemble.c @@ -18,6 +18,7 @@ #include "llvm-c/Target.h" #include #include +#include static void pprint(int pos, unsigned char *buf, int len, const char *disasm) { int i; @@ -33,13 +34,15 @@ static void pprint(int pos, unsigned char *buf, int len, const char *disasm) { printf(" %s\n", disasm); } -static void do_disassemble(const char *triple, unsigned char *buf, int siz) { - LLVMDisasmContextRef D = LLVMCreateDisasm(triple, NULL, 0, NULL, NULL); +static void do_disassemble(const char *triple, const char *features, + unsigned char *buf, int siz) { + LLVMDisasmContextRef D = LLVMCreateDisasmCPUFeatures(triple, "", features, + NULL, 0, NULL, NULL); char outline[1024]; int pos; if (!D) { - printf("ERROR: Couldn't create disassebler for triple %s\n", triple); + printf("ERROR: Couldn't create disassembler for triple %s\n", triple); return; } @@ -62,19 +65,22 @@ static void do_disassemble(const char *triple, unsigned char *buf, int siz) { static void handle_line(char **tokens, int ntokens) { unsigned char disbuf[128]; size_t disbuflen = 0; - char *triple = tokens[0]; + const char *triple = tokens[0]; + const char *features = tokens[1]; int i; - printf("triple: %s\n", triple); + printf("triple: %s, features: %s\n", triple, features); + if (!strcmp(features, "NULL")) + features = ""; - for (i = 1; i < ntokens; i++) { + for (i = 2; i < ntokens; i++) { disbuf[disbuflen++] = strtol(tokens[i], NULL, 16); if (disbuflen >= sizeof(disbuf)) { fprintf(stderr, "Warning: Too long line, truncating\n"); break; } } - do_disassemble(triple, disbuf, disbuflen); + do_disassemble(triple, features, disbuf, disbuflen); } int disassemble(void) {