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>