Help with Instruction Expansion on Mips

Hi everyone,

I am a newbie to LLVM. I am trying to ban some of instructions in Mips Instruction, for example, lh, lhu, sh, and etc.
I have tried to directly comment lh, lhu, and sh to make llvm not to choose these instruction when compiling, however, it usually cause a ‘can not select …’ error when using ‘short’ data type in source code.
Then I tried to expand these instructions in EmitInstrWithCustomInserter in file lib/Target/Mips/MipsISelLowering.cpp, just as commit in:

https://github.com/geraint0923/LLVM-ThuMips/commit/6a9ca907f3e945c2bb1f9627e0e5fdcbd7964da2

It works fine for lh and lhu, and fails for sh:
when expanding sh, there are four instruction, but in *.s generated by modified llvm’s llc, there are only two instructions which are both sb, addiu and srl are gone.

Is there anything wrong when expanding?
And I wonder if there is another method to do the same thing.

Any help will be appreciated.

Thanks,
Yang

why do you want to "ban" certain instructions?

is this for some architectural variant?

the compiler is trying to match patterns from the target independent part of the code generator.

if you remove instructions, the compiler in many cases will no longer be able to match certain patterns
and you will get thos "can not select" messages.

Thanks for your reply.

We are trying to implement a simple Mips-based CPU with just for teaching purpose, so we delete some instructions which are not commonly used, thus the task won’t be too hard for students. I am responsible for modifying the compiler so that the compiler won’t emit unsupported instructions.

In order to avoid “can not select” error, I am trying to expand these instructions when meeting them.

So what should I modify to achieve the goal?

Thanks,
Yang

YOu have to look for which DAG fragments are not being matched.

Then you can create patterns for those using alternate sequences.

When you disablea given instruction, don't just disable it, but also look at what pattern it was matching.

Then create a patten for that using remaining instructions or in some cases you might have to call a library function, as in the case of floating pointing or maybe even integer multiply if you don't implement that.

In some cases, the original instruction may be directly emitted by the compiler, outside of the framework td files. Then you'll have to modify c++ code and emit an alternate sequence.

Here are some simple patterns from the MipsInstrInfo.td

//===----------------------------------------------------------------------===//
// Arbitrary patterns that map to one or more instructions
//===----------------------------------------------------------------------===//

// Small immediates
def : MipsPat<(i32 immSExt16:$in),
               (ADDiu ZERO, imm:$in)>;
def : MipsPat<(i32 immZExt16:$in),
               (ORi ZERO, imm:$in)>;
def : MipsPat<(i32 immLow16Zero:$in),
               (LUi (HI16 imm:$in))>;

Here are some which have several instructions

multiclass SetgePats<RegisterClass RC, Instruction SLTOp, Instruction

{

   def : MipsPat<(setge RC:$lhs, RC:$rhs),
                 (XORi (SLTOp RC:$lhs, RC:$rhs), 1)>;
   def : MipsPat<(setuge RC:$lhs, RC:$rhs),
                 (XORi (SLTuOp RC:$lhs, RC:$rhs), 1)>;
}

Thanks very much for your help.

I think I have understood how to match a pattern and emit a instruction for the pattern. But how can I emit multi-instructions (instruction sequence) for a matching pattern? Is there a sample in llvm’s source code?

Thanks,
Yang