Hi, all: Now I'm working on writing a backend for Moto MCore, but I don't know how to describe some instructions. First, I've already written MCoreRegisterInfo.td like these: class MCoreReg<bits<4> num, string name> : Register<name> { let Namespace = "MCore"; field bits<4> Num = num; } def R0 : MCoreReg< 0, "R0">, DwarfRegNum<[ 0]>; ... def R15 : MCoreReg<15, "R15">, DwarfRegNum<[15]>; Then, I wrote MCoreInstrFormats.td: class MCoreInst<dag outs, dag ins, string asmstr, list<dag> pattern> : Instruction { field bits<16> Inst; let Namespace = "MCore"; dag OutOperandList = outs; dag InOperandList = ins; let AsmString = asmstr; let Pattern = pattern; } // Base Plus Index Addressing Mode class MABase<dag outs, dag ins, string asmstr, list<dag> pattern> : MCoreInst<outs, ins, asmstr, pattern> { bits<2> subOp; bits<4> Rx; let Inst{15-6}= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; let Inst{5-4} = subOp; let Inst{3-0} = Rx; } // Load/Store Register Quadrant Mode class QuadR<bits<2> subOpVal, dag outs, dag ins, string asmstr, list<dag> pattern> : MABase<outs, ins, asmstr, pattern> { let subOp = subOpVal; } // Load/Store Multiple Register Mode class MultR<bits<2> subOpVal, dag outs, dag ins, string asmstr, list<dag> pattern> : MABase<outs, ins, asmstr, pattern> { let subOp = subOpVal; } Finally, I don't know how to describe following instructions in MCoreInstrInfo.td, because of its variable ins/outs. Or what other files should I use to finish this description? // LDQ, STQ, LDM and STM are Mapping Error // Load/Store Register Quadrant Mode def LDQ : QuadR<0x0, // FIXME p81 (outs GPRs:$Rx), (ins GPRs:R4, GPRs:R5, GPRs:R6, GPRs:R7), "ldq R4-R7, ($Rx)", []>; def STQ : QuadR<0x1, (outs GPRs:R4, GPRs:R5, GPRs:R6, GPRs:R7), (ins GPRs:$Rx), "stq R4-R7, ($Rx)", []>; // Load/Store Multiple Register Mode def LDM : MultR<0x2, // FIXME p80 (outs GPRs:R0), (ins GPRs:$Rf), "ldm $Rf-R15, (R0)", []>; def STM : MultR<0x3, // FIXME p109 (outs GPRs:$Rf), (ins GPRs:R0), "stm $Rf-R15, (R0)", []>; Info below comes from MCore Programmers Reference Manual: LDQ - Load Register Quadrant from Memory Operation: Destination registers ← memory; Assembler Syntax: ldq r4–r7,(rx) Description: The ldq instruction is used to load four registers (R4–R7) from memory. Register X points to the location of the first transfer. Registers are loaded in increasing significance from ascending memory locations. If register X is specified to be R4, R5, R6, or R7, the instruction form is considered invalid, and the results are undefined. For valid instruction forms, register X is not affected or updated. Condition Code: Unaffected Instruction Fields: Register X — Specifies the base address for the transfers. Register X should not specify R4, R5, R6, or R7. LDM - Load Multiple Registers from Memory Operation: Destination Registers ← Memory Assembler Syntax: ldm rf–r15,(r0) Description: The ldm instruction is used to load a contiguous range of registers from the stack. Register 0 (R0) serves as the base address pointer for this form. Registers Rf–R15 are loaded in increasing significance from ascending memory locations. Rf may not specify R0 or R15; these instruction forms are considered illegal, although they are not guaranteed to be detected by hardware. For valid instruction forms, register 0 (R0) is not affected or updated. Condition Code: Unaffected Instruction Fields: Register First field — Specifies the first register to be transferred. Only R1–R14 should be specified. STM - Store Multiple Registers to Memory Operation: Memory ← Source Registers Assembler Syntax: stm rf–r15,(r0) Description: Store multiple registers to memory. The stm instruction is used to transfer a contiguous range of registers to the stack. Register 0 (R0) serves as the base address pointer for this form. Registers Rf –R15 are stored in increasing significance to ascending memory locations. Register 0 (R0) is not affected/updated. Rf may not specify R0 or R15; these instruction forms are considered illegal, although they are not guaranteed to be detected by hardware. Condition Code: Instruction Fields: same to LDM STQ - Store Register Quadrant to Memory Operation: Memory ← Source Registers Assembler Syntax: stq r4–r7,(rx) Description: Store register quadrant to memory. The stq instruction is used to transfer the contents of four registers (R4–R7) to memory. Register X points to the location of the first transfer. Registers are stored in increasing significance to ascending memory locations. Register X is not affected or updated. If register X is part of the quadrant being transferred, the value stored for this register is undefined. Condition Code: Instruction Fields: same to LDQ -- Yours truly, Zhang Zuyu(张祖羽) ----------------------------------------------------------- College of Computer Science and Technology, Harbin Engineering University -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110623/6fc7245f/attachment.html>
Anton Korobeynikov
2011-Jun-23 13:51 UTC
[LLVMdev] Instr Description Problem of MCore Backend
Hello> Finally, I don't know how to describe following instructions in > MCoreInstrInfo.td, because of its variable ins/outs. Or what other files > should I use to finish this description?Do you need the isel support for them? If yes, then you should custom isel them. iirc ARM and SystemZ backends have similar instructions, while only the first one supports full isel for them. In short: you should recognize the consecutive loads / stores and turn them into load/store multiple. If you just need the have assembler support, then you don't need to specify the exact operands there (for "Q" instructions), since they are fixed. Just provide the list of used / clobbered instructions. -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University
Hi, I have another puzzle. In SPARC, load / store instructions form as below: def MEMri : Operand<i32> { let PrintMethod = "printMemOperand"; let MIOperandInfo = (ops IntRegs, i32imm); } def ADDRri : ComplexPattern<i32, 2, "SelectADDRri", [frameindex], []>; def LDSBri : F3_2<3, 0bxxxxx, (outs IntRegs:$dst), (ins MEMri:$addr), "ldsb [$addr], $dst", [(set IntRegs:$dst, (sextloadi8 ADDRri:$addr))]>; def STBri : F3_2<3, 0bxxxx, (outs), (ins MEMri:$addr, IntRegs:$src), "stb $src, [$addr]", [(truncstorei8 IntRegs:$src, ADDRri:$addr)]>; I means that in Sparc, the memory address in ld/st instruction is one operand, but in MCore, ld.b, which means load byte, forms as "ld.b Rz, (Rx, Disp)". It means that move MEM[Rx + unsigned Imm4 << 1] to Rz. Disp is obtained by taking the Imm4 field, scaling by the size of the load, and zero-extending. def disp : Operand<i32> { let PrintMethod = "printZExtConstOperand<4>"; // I knew it's wrong code, I need to shift left by {0, 1, 2} here, // and then zero-extend. // 0 for word, 1 for byte, and 2 for halfword. } def LDB : MARc4<0xa, (outs GPRs:$Rz), (ins GPRs:$Rx, disp:$Imm4), "ld.b $Rz, ($Rx, $Imm4)", // how do I use $Imm4 to form a $Disp by shifting left once? [(set GPRs:$Rz, (loadi8 (add GPRs:$Rx, uimm4:$Imm4)))]>; // and how do I use ComplexPattern to form a memory address? STB means MEM[Rx + unsigned Imm4 << 1] <- Rz def STB : MARc4<0xb, (outs), (ins GPRs:$Rz, disp:$Imm4. GPRs:$Rx), "st.b $Rz, ($Rx, $Imm4)", [(truncstorei8 GPRs:$Rz, (add GPRs:$Rx, uimm4:$Imm4))]>; // how to deal with uimm4? I have no idea to construct it as a calculated memory address. In MCore, Memory access to unsigned byte-sized data is directly supported through the ld.b(load byte) and st.b (store byte) instructions. Signed byte-sized access requires a sextb (sign extension) instruction after the ld.b. That's why I use loadi8 instead of zextloadi8 in Sparc. Thanks a lot! On Thu, Jun 23, 2011 at 9:51 PM, Anton Korobeynikov <anton at korobeynikov.info> wrote:> Hello > > > Finally, I don't know how to describe following instructions in > > MCoreInstrInfo.td, because of its variable ins/outs. Or what other files > > should I use to finish this description? > Do you need the isel support for them? If yes, then you should custom > isel them. iirc ARM and SystemZ backends have similar instructions, > while only the first one supports full isel for them. In short: you > should recognize the consecutive loads / stores and turn them into > load/store multiple. > > Yes, I would implement whole back-end to assembly code printing.> If you just need the have assembler support, then you don't need to > specify the exact operands there (for "Q" instructions), since they > are fixed. Just provide the list of used / clobbered instructions. > > Yeah, It's a good idea!> -- > With best regards, Anton Korobeynikov > Faculty of Mathematics and Mechanics, Saint Petersburg State University >-- Yours truly, Zhang Zuyu(张祖羽) ----------------------------------------------------------- College of Computer Science and Technology, Harbin Engineering University -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110628/1b3233a7/attachment.html>