[llvm-commits] [PATCH] JIT support for ARM
Evan Cheng
evan.cheng at apple.com
Fri Aug 17 12:02:24 PDT 2007
Very good progress. Thanks!
Comments inline.
Evan
> Index: lib/Target/ARM/ARMJITInfo.cpp
> ===================================================================
> --- lib/Target/ARM/ARMJITInfo.cpp (revis√£o 41124)
> +++ lib/Target/ARM/ARMJITInfo.cpp (cópia de trabalho)
> @@ -21,12 +21,7 @@
> using namespace llvm;
>
> void ARMJITInfo::replaceMachineCodeForFunction(void *Old, void
> *New) {
> - unsigned char *OldByte = (unsigned char *)Old;
> - *OldByte++ = 0xEA; // Emit B opcode.
> - unsigned *OldWord = (unsigned *)OldByte;
> - unsigned NewAddr = (intptr_t)New;
> - unsigned OldAddr = (intptr_t)OldWord;
> - *OldWord = NewAddr - OldAddr - 4; // Emit PC-relative addr of New
> code.
> + assert(0);
Please use abort() instead so it does what's expected in non-debug
build.
> }
>
> /// JITCompilerFunction - This contains the address of the JIT
> function used to
> @@ -65,7 +60,7 @@
> #endif
> }
>
> -/// ARMCompilationCallbackC - This is the target-specific function
> invoked by the
> +/// ARMCompilationCallbackC - This i s the target-specific function
> invoked by the
i s -> is :-)
Also, why the name "ARMCompilationCallbackC"? Is it language specific?
> /// function stub when we did not know the real target of a call.
> This function
> /// must locate the start of the stub or call site and pass it into
> the JIT
> /// compiler function.
> @@ -80,18 +75,16 @@
> << ": Resolving call to function: "
> << TheVM->getFunctionReferencedName((void*)RetAddr) << "\n";
> #endif
> + intptr_t Addr = RetAddr - 4;
>
> - // Sanity check to make sure this really is a branch and link
> instruction.
> - assert(((unsigned char*)RetAddr-1)[3] == 0xEB && "Not a branch
> and link instr!");
> + intptr_t NewVal = (intptr_t)JITCompilerFunction((void*)Addr);
Does a similar assertion makes sense here?
>
> - intptr_t NewVal = (intptr_t)JITCompilerFunction((void*)RetAddr);
> -
> // Rewrite the call target... so that we don't end up here every
> time we
> // execute the call.
> - *(intptr_t *)RetAddr = (intptr_t)(NewVal-RetAddr-4);
> + *(intptr_t *)Addr = NewVal;
>
> // Change the return address to reexecute the branch and link
> instruction...
> - *RetAddrLoc -= 1;
> + *RetAddrLoc -= 8;
> }
>
> TargetJITInfo::LazyResolverFn
> @@ -101,23 +94,23 @@
> }
>
> void *ARMJITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter
> &MCE) {
> - unsigned addr = (intptr_t)Fn-MCE.getCurrentPCValue()-4;
> + unsigned addr = (intptr_t)Fn;
> // If this is just a call to an external function, emit a branch
> instead of a
> // call. The code is the same except for one bit of the last
> instruction.
> if (Fn != (void*)(intptr_t)ARMCompilationCallback) {
> - MCE.startFunctionStub(4, 2);
> - MCE.emitByte(0xEA); // branch to the corresponding function addr
> - MCE.emitByte((unsigned char)(addr >> 0));
> - MCE.emitByte((unsigned char)(addr >> 8));
> - MCE.emitByte((unsigned char)(addr >> 16));
> - return MCE.finishFunctionStub(0);
> + // branch to the corresponding function addr
> + MCE.startFunctionStub(8, 4);
> + MCE.emitWordLE(0xE51FF004); // LDR PC, [PC,#-4]
This is ok.... But I would rather see you refactor
getBinaryCodeForInstr() so you can "manufacture" the value by passing
it ARM::LDR, ARM::PC, etc.? Do you think that's possible?
Also, in Emitter::getBinaryCodeForInstr():
unsigned Emitter::getBinaryCodeForInstr(const MachineInstr &MI) {
const TargetInstrDescriptor *Desc = MI.getInstrDescriptor();
const unsigned opcode = MI.getOpcode();
unsigned Value = 0xE0000000;
Comments? What is 0xe000000?
unsigned op;
switch (Desc->TSFlags & ARMII::AddrModeMask) {
case ARMII::AddrModeNone: {
switch(Desc->TSFlags & ARMII::FormMask) {
default: {
assert(0 && "Unknown instruction subtype!");
if(opcode == ARM::CLZ) {
// set first operand
op = getMachineOpValue(MI,0);
Value |= op << 12;
Can 12 (and all the magic shift amounts in this function) be defined
in ARMII enum? So you add comments there rather than in this code.
> + MCE.emitWordLE(addr);
> } else {
> - MCE.startFunctionStub(5, 2);
> - MCE.emitByte(0xEB); // branch and link to the corresponding
> function addr
> + // branch and link to the corresponding function addr
> + MCE.startFunctionStub(20, 4);
> + MCE.emitWordLE(0xE92D4800); // STMFD SP!, [R11, LR]
> + MCE.emitWordLE(0xE28FE004); // ADD LR, PC, #4
> + MCE.emitWordLE(0xE51FF004); // LDR PC, [PC,#-4]
> + MCE.emitWordLE(addr);
> + MCE.emitWordLE(0xE8BD8800); // LDMFD SP!, [R11, PC]
Ditto.
> }
> - MCE.emitByte((unsigned char)(addr >> 0));
> - MCE.emitByte((unsigned char)(addr >> 8));
> - MCE.emitByte((unsigned char)(addr >> 16));
>
> return MCE.finishFunctionStub(0);
> }
> @@ -133,14 +126,22 @@
> switch ((ARM::RelocationType)MR->getRelocationType()) {
> case ARM::reloc_arm_relative: {
> // PC relative relocation
> - *((unsigned*)RelocPos) += (unsigned)ResultPtr;
> + ResultPtr = ResultPtr-(intptr_t)RelocPos-8;
> + if (ResultPtr >= 0)
> + *((unsigned*)RelocPos) |= 1 << 23;
> + else {
> + ResultPtr *= -1;
> + *((unsigned*)RelocPos) &= 0xFF7FFFFF;
Please explain what's going on here? :-)
> + }
> + *((unsigned*)RelocPos) |= (unsigned)ResultPtr;
> + *((unsigned*)RelocPos) |= 0xF << 16;
> break;
> }
> - case ARM::reloc_arm_absolute:
> - break;
> case ARM::reloc_arm_branch: {
> // relocation to b and bl instructions
> - ResultPtr = (ResultPtr-(intptr_t)RelocPos) >> 2;
> + ResultPtr = ResultPtr-(intptr_t)RelocPos-8;
> + ResultPtr = (ResultPtr & 0x03FFFFFC) >> 2;
> + //assert(ResultPtr >= -33554432 && ResultPtr <= 33554428);
> *((unsigned*)RelocPos) |= ResultPtr;
> break;
> }
> Index: lib/Target/ARM/ARMInstrInfo.td
> ===================================================================
> --- lib/Target/ARM/ARMInstrInfo.td (revis√£o 41124)
> +++ lib/Target/ARM/ARMInstrInfo.td (cópia de trabalho)
> @@ -342,33 +342,38 @@
>
> def Pseudo : Format<1>;
> def MulFrm : Format<2>;
> -def Branch : Format<3>;
> -def BranchMisc : Format<4>;
> +def MulSMLAW : Format<3>;
> +def MulSMULW : Format<4>;
> +def MulSMLA : Format<5>;
> +def MulSMUL : Format<6>;
> +def Branch : Format<7>;
> +def BranchMisc : Format<8>;
>
> -def DPRdIm : Format<5>;
> -def DPRdReg : Format<6>;
> -def DPRdSoReg : Format<7>;
> -def DPRdMisc : Format<8>;
> -def DPRnIm : Format<9>;
> -def DPRnReg : Format<10>;
> -def DPRnSoReg : Format<11>;
> -def DPRIm : Format<12>;
> -def DPRReg : Format<13>;
> -def DPRSoReg : Format<14>;
> -def DPRImS : Format<15>;
> -def DPRRegS : Format<16>;
> -def DPRSoRegS : Format<17>;
> +def DPRdIm : Format<9>;
> +def DPRdReg : Format<10>;
> +def DPRdSoReg : Format<11>;
> +def DPRdMisc : Format<12>;
> +def DPRnIm : Format<13>;
> +def DPRnReg : Format<14>;
> +def DPRnSoReg : Format<15>;
> +def DPRIm : Format<16>;
> +def DPRReg : Format<17>;
> +def DPRSoReg : Format<18>;
> +def DPRImS : Format<19>;
> +def DPRRegS : Format<20>;
> +def DPRSoRegS : Format<21>;
>
> -def LdFrm : Format<18>;
> -def StFrm : Format<19>;
> +def LdFrm : Format<22>;
> +def StFrm : Format<23>;
>
> -def ArithMisc : Format<20>;
> -def ThumbFrm : Format<21>;
> -def VFPFrm : Format<22>;
> +def ArithMisc : Format<24>;
> +def ThumbFrm : Format<25>;
> +def VFPFrm : Format<26>;
>
>
>
> //
> =
> =
> =
> ----------------------------------------------------------------------=
> ==//
> +
> // ARM Instruction templates.
> //
>
> @@ -815,7 +820,7 @@
> [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
>
> // Load doubleword
> -def LDRD : AI3<0x0, (outs GPR:$dst), (ins addrmode3:$addr), LdFrm,
> +def LDRD : AI3<0xD, (outs GPR:$dst), (ins addrmode3:$addr), LdFrm,
> "ldr", "d $dst, $addr",
> []>, Requires<[IsARM, HasV5T]>;
>
> @@ -877,7 +882,7 @@
> [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
>
> // Store doubleword
> -def STRD : AI3<0x0, (outs), (ins GPR:$src, addrmode3:$addr), StFrm,
> +def STRD : AI3<0xF, (outs), (ins GPR:$src, addrmode3:$addr), StFrm,
> "str", "d $src, $addr",
> []>, Requires<[IsARM, HasV5T]>;
>
> @@ -1125,76 +1130,86 @@
> [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:
> $b)))]>,
> Requires<[IsARM, HasV6]>;
>
> -multiclass AI_smul<bits<4> opcod, string opc, PatFrag opnode> {
> - def BB : AI<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), MulFrm,
> +multiclass AI_smul<string opc, PatFrag opnode> {
> + def BB : AI<0x8, (outs GPR:$dst), (ins GPR:$a, GPR:$b), MulSMUL,
> !strconcat(opc, "bb"), " $dst, $a, $b",
> [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
> (sext_inreg GPR:$b, i16)))]>,
> Requires<[IsARM, HasV5TE]>;
> - def BT : AI<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), MulFrm,
> +
> + def BT : AI<0xC, (outs GPR:$dst), (ins GPR:$a, GPR:$b), MulSMUL,
> !strconcat(opc, "bt"), " $dst, $a, $b",
> [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
> (sra GPR:$b, 16)))]>,
> Requires<[IsARM, HasV5TE]>;
> - def TB : AI<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), MulFrm,
> +
> + def TB : AI<0xA, (outs GPR:$dst), (ins GPR:$a, GPR:$b), MulSMUL,
> !strconcat(opc, "tb"), " $dst, $a, $b",
> [(set GPR:$dst, (opnode (sra GPR:$a, 16),
> (sext_inreg GPR:$b, i16)))]>,
> Requires<[IsARM, HasV5TE]>;
> - def TT : AI<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), MulFrm,
> +
> + def TT : AI<0xE, (outs GPR:$dst), (ins GPR:$a, GPR:$b), MulSMUL,
> !strconcat(opc, "tt"), " $dst, $a, $b",
> [(set GPR:$dst, (opnode (sra GPR:$a, 16),
> (sra GPR:$b, 16)))]>,
> Requires<[IsARM, HasV5TE]>;
> - def WB : AI<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), MulFrm,
> +
> + def WB : AI<0xA, (outs GPR:$dst), (ins GPR:$a, GPR:$b), MulSMULW,
> !strconcat(opc, "wb"), " $dst, $a, $b",
> [(set GPR:$dst, (sra (opnode GPR:$a,
> (sext_inreg GPR:$b, i16)),
> 16))]>,
> Requires<[IsARM, HasV5TE]>;
> - def WT : AI<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), MulFrm,
> +
> + def WT : AI<0xE, (outs GPR:$dst), (ins GPR:$a, GPR:$b), MulSMULW,
> !strconcat(opc, "wt"), " $dst, $a, $b",
> [(set GPR:$dst, (sra (opnode GPR:$a,
> (sra GPR:$b, 16)), 16))]>,
> Requires<[IsARM, HasV5TE]>;
> }
>
> -multiclass AI_smla<bits<4> opcod, string opc, PatFrag opnode> {
> - def BB : AI<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:
> $acc), MulFrm,
> +
> +multiclass AI_smla<string opc, PatFrag opnode> {
> + def BB : AI<0x8, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
> MulSMLA,
> !strconcat(opc, "bb"), " $dst, $a, $b, $acc",
> [(set GPR:$dst, (add GPR:$acc,
> (opnode (sext_inreg GPR:$a, i16),
> (sext_inreg GPR:$b, i16))))]>,
> Requires<[IsARM, HasV5TE]>;
> - def BT : AI<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:
> $acc), MulFrm,
> +
> + def BT : AI<0xC, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
> MulSMLA,
> !strconcat(opc, "bt"), " $dst, $a, $b, $acc",
> [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg
> GPR:$a, i16),
> (sra GPR:$b,
> 16))))]>,
> Requires<[IsARM, HasV5TE]>;
> - def TB : AI<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:
> $acc), MulFrm,
> +
> + def TB : AI<0xA, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
> MulSMLA,
> !strconcat(opc, "tb"), " $dst, $a, $b, $acc",
> [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a,
> 16),
> (sext_inreg GPR:
> $b, i16))))]>,
> Requires<[IsARM, HasV5TE]>;
> - def TT : AI<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:
> $acc), MulFrm,
> +
> + def TT : AI<0xE, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
> MulSMLA,
> !strconcat(opc, "tt"), " $dst, $a, $b, $acc",
> [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a,
> 16),
> (sra GPR:$b,
> 16))))]>,
> Requires<[IsARM, HasV5TE]>;
>
> - def WB : AI<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:
> $acc), MulFrm,
> + def WB : AI<0xA, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
> MulSMLAW,
> !strconcat(opc, "wb"), " $dst, $a, $b, $acc",
> [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
> (sext_inreg GPR:$b,
> i16)), 16)))]>,
> Requires<[IsARM, HasV5TE]>;
> - def WT : AI<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:
> $acc), MulFrm,
> +
> + def WT : AI<0xE, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
> MulSMLAW,
> !strconcat(opc, "wt"), " $dst, $a, $b, $acc",
> [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
> (sra GPR:$b,
> 16)), 16)))]>,
> Requires<[IsARM, HasV5TE]>;
> }
>
> -defm SMUL : AI_smul<0x0, "smul", BinOpFrag<(mul node:$LHS, node:
> $RHS)>>;
> -defm SMLA : AI_smla<0x0, "smla", BinOpFrag<(mul node:$LHS, node:
> $RHS)>>;
> +defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
> +defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
>
> // TODO: Halfword multiple accumulate long: SMLAL<x><y>
> // TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD,
> SMLALD, SMLSLD
> Index: lib/Target/ARM/ARMCodeEmitter.cpp
> ===================================================================
> --- lib/Target/ARM/ARMCodeEmitter.cpp (revis√£o 41124)
> +++ lib/Target/ARM/ARMCodeEmitter.cpp (cópia de trabalho)
> @@ -54,9 +54,9 @@
> }
>
> void emitInstruction(const MachineInstr &MI);
> - unsigned getBinaryCodeForInstr(const MachineInstr &MI);
> int getMachineOpValue(const MachineInstr &MI, unsigned OpIndex);
> unsigned getBaseOpcodeFor(const TargetInstrDescriptor *TID);
> + unsigned getBinaryCodeForInstr(const MachineInstr &MI);
>
> void emitGlobalAddressForCall(GlobalValue *GV, bool
> DoesntNeedStub);
> void emitExternalSymbolAddress(const char *ES, unsigned Reloc);
> @@ -64,6 +64,7 @@
> int Disp = 0, unsigned PCAdj = 0 );
> void emitJumpTableAddress(unsigned JTI, unsigned Reloc,
> unsigned PCAdj = 0);
> + void emitGlobalConstant(const Constant *CV);
>
> private:
> int getShiftOp(const MachineOperand &MO);
> @@ -137,7 +138,7 @@
> MO.isConstantPoolIndex() || MO.isJumpTableIndex()) {
>
> if (MO.isGlobalAddress()) {
> - emitGlobalAddressForCall(MO.getGlobal(), true);
> + emitGlobalAddressForCall(MO.getGlobal(), false);
> } else if (MO.isExternalSymbol()) {
> emitExternalSymbolAddress(MO.getSymbolName(),
> ARM::reloc_arm_relative);
> } else if (MO.isConstantPoolIndex()) {
> @@ -186,8 +187,6 @@
> Reloc, JTI,
> PCAdj));
> }
>
> -
> -
> void Emitter::emitInstruction(const MachineInstr &MI) {
> NumEmitted++; // Keep track of the # of mi's emitted
> MCE.emitWordLE(getBinaryCodeForInstr(MI));
> @@ -215,6 +214,37 @@
> }
> break;
> }
> + case ARMII::MulSMLAW:
> + case ARMII::MulSMULW:
> + Value |= 1 << 21;
> + case ARMII::MulSMLA:
> + case ARMII::MulSMUL: {
> + Value |= 1 << 24;
> +
> + unsigned char BaseOpcode = getBaseOpcodeFor(Desc);
> + Value |= BaseOpcode << 4;
> +
> + unsigned Format = (Desc->TSFlags & ARMII::FormMask);
> +
> + if (Format == ARMII::MulSMUL)
> + Value |= 1 << 22;
> +
> + op = getMachineOpValue(MI,0);
> + Value |= op << 16;
> +
> + op = getMachineOpValue(MI,1);
> + Value |= op;
> +
> + op = getMachineOpValue(MI,2);
> + Value |= op << 8;
> +
> + if (Format != ARMII::MulSMULW && Format != ARMII::MulSMUL) {
> + op = getMachineOpValue(MI,3);
> + Value |= op << 12;
> + }
> +
> + break;
> + }
> case ARMII::MulFrm: {
> Value |= 9 << 4;
>
> @@ -460,7 +490,7 @@
> Value |= 1 << 24;
>
> unsigned Format = (Desc->TSFlags & ARMII::FormMask);
> - if (Format == ARMII::LdFrm)
> + if (Format == ARMII::LdFrm && opcode != ARM::LDRD)
Instead of special casing it for LDRD, perhaps add a LB (L bit) class
and attach to the other instructions that need it? See
X86InstrFormats.td for examples (e.g. TB). I'd like to see PUWLSH bits
modeled more clearly.
> Value |= 1 << 20;
>
> unsigned char BaseOpcode = getBaseOpcodeFor(Desc);
> Index: lib/Target/ARM/ARMInstrInfo.h
> ===================================================================
> --- lib/Target/ARM/ARMInstrInfo.h (revis√£o 41124)
> +++ lib/Target/ARM/ARMInstrInfo.h (cópia de trabalho)
> @@ -73,43 +73,46 @@
>
> // Multiply instructions
> MulFrm = 2 << FormShift,
> + MulSMLAW = 3 << FormShift,
> + MulSMULW = 4 << FormShift,
> + MulSMLA = 5 << FormShift,
> + MulSMUL = 6 << FormShift,
>
> // Branch instructions
> - Branch = 3 << FormShift,
> - BranchMisc = 4 << FormShift,
> + Branch = 7 << FormShift,
> + BranchMisc = 8 << FormShift,
>
> // Data Processing instructions
> - DPRdIm = 5 << FormShift,
> - DPRdReg = 6 << FormShift,
> - DPRdSoReg = 7 << FormShift,
> - DPRdMisc = 8 << FormShift,
> + DPRdIm = 9 << FormShift,
> + DPRdReg = 10 << FormShift,
> + DPRdSoReg = 11 << FormShift,
> + DPRdMisc = 12 << FormShift,
>
> - DPRnIm = 9 << FormShift,
> - DPRnReg = 10 << FormShift,
> - DPRnSoReg = 11 << FormShift,
> + DPRnIm = 13 << FormShift,
> + DPRnReg = 14 << FormShift,
> + DPRnSoReg = 15 << FormShift,
>
> - DPRIm = 12 << FormShift,
> - DPRReg = 13 << FormShift,
> - DPRSoReg = 14 << FormShift,
> + DPRIm = 16 << FormShift,
> + DPRReg = 17 << FormShift,
> + DPRSoReg = 18 << FormShift,
>
> - DPRImS = 15 << FormShift,
> - DPRRegS = 16 << FormShift,
> - DPRSoRegS = 17 << FormShift,
> + DPRImS = 19 << FormShift,
> + DPRRegS = 20 << FormShift,
> + DPRSoRegS = 21 << FormShift,
>
> // Load and Store
> - LdFrm = 18 << FormShift,
> - StFrm = 19 << FormShift,
> + LdFrm = 22 << FormShift,
> + StFrm = 23 << FormShift,
>
> // Miscellaneous arithmetic instructions
> - ArithMisc = 20 << FormShift,
> + ArithMisc = 24 << FormShift,
>
> // Thumb format
> - ThumbFrm = 21 << FormShift,
> + ThumbFrm = 25 << FormShift,
>
> // VFP format
> - VPFFrm = 22 << FormShift
> + VPFFrm = 26 << FormShift
>
> -
> };
> }
>
> Index: lib/Target/ARM/ARMRelocations.h
> ===================================================================
> --- lib/Target/ARM/ARMRelocations.h (revis√£o 41124)
> +++ lib/Target/ARM/ARMRelocations.h (cópia de trabalho)
> @@ -21,8 +21,6 @@
> enum RelocationType {
> reloc_arm_relative,
>
> - reloc_arm_absolute,
> -
> reloc_arm_branch
> };
> }
On Aug 16, 2007, at 2:07 PM, Raul Fernandes Herbster wrote:
> Multiply instructions are being generated. ARM/JIT runs an
> application with no calls to local functions, but library functions
> calls are supported. I hope fix such problem soon. Please, send me
> any feedback.
>
> Thanks in advance, Raul.
>
> --
> Raul Fernandes Herbster
> Embedded and Pervasive Computing Laboratory - embedded.dee.ufcg.edu.br
> Electrical Engineering Department - DEE - www.dee.ufcg.edu.br
> Electrical Engineering and Informatics Center - CEEI
> Federal University of Campina Grande - UFCG - www.ufcg.edu.br
> Caixa Postal 10105
> 58109-970 Campina Grande - PB - Brasil
> <patch>_______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20070817/7fc9984e/attachment.html>
More information about the llvm-commits
mailing list