<div dir="ltr"><div>Hi Alex,<br><br></div>That helped a lot. I appreciate it. :-)<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Dec 7, 2015 at 1:24 PM, Alex Bradbury <span dir="ltr"><<a href="mailto:asb@asbradbury.org" target="_blank">asb@asbradbury.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 7 December 2015 at 11:51, Sky Flyer via llvm-dev<br>
<span class=""><<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br>
> Dear all,<br>
><br>
> I have written an assembler which reads assembly instructions and produces<br>
> the equivalent binary. I have a problem. Although I set the bit range and<br>
> immediate type for an instruction like add which accepts a register and an<br>
> immediate value, I can simply overflow that value and llvm/tablegen doesn't<br>
> care!<br>
><br>
> for example for a i8imm imm value (bits<8> val) these two produce the same<br>
> output:<br>
><br>
> add r0 0<br>
> add r0 256<br>
><br>
> whose responsibility is to check the integer boundary in the assembly<br>
> parser?<br>
<br>
</span>It's worth looking at what some other targets do here (e.g. SystemZ<br>
handles this pretty cleanly, and MIPS is adding better error reporting<br>
<a href="http://reviews.llvm.org/D15226" rel="noreferrer" target="_blank">http://reviews.llvm.org/D15226</a>).<br>
<br>
It helps to take a look at include/llvm/Target/Target.td. the Operand<br>
class has a field ParserMatchClass of type AsmOperandClass, which by<br>
default contains the ImmAsmOperand instance which ultimately means<br>
that isImm() in your AsmParser will be called to check the operand. To<br>
customise the behaviour to for instance, check the immediate is in the<br>
appropriate range you can provide your own AsmOperandClass. e.g.:<br>
<br>
class ImmediateAsmOperand<string name><br>
  : AsmOperandClass {<br>
  let Name = name;<br>
  let RenderMethod = "addImmOperands";<br>
  let DiagnosticType = !strconcat("Invalid", name);<br>
}<br>
<br>
def imm8 : Operand<i32> {<br>
  let ParserMatchClass = ImmediateAsmOperand<"Imm8">;<br>
}<br>
<br>
With the Name field of the ParserMatchClass set to Imm8, You now just<br>
need to provide an isImm8() implementation in MyTargetAsmParser.<br>
You'll also want to check for Match_InvalidImm8 as a result of<br>
MatchInstructionImpl to provide a more useful error reporting than<br>
"invalid operand for instruction". To use Match_InvalidImm8, you'll<br>
need to make sure you do something like the below (just grep the<br>
sources for GET_OPERAND_DIAGNOSTIC_TYPES to see other targets doing<br>
the same).<br>
<br>
  enum MyTargetMatchResultTy {<br>
    Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,<br>
#define GET_OPERAND_DIAGNOSTIC_TYPES<br>
#include "MyTargetGenAsmMatcher.inc"<br>
#undef GET_OPERAND_DIAGNOSTIC_TYPES<br>
  };<br>
<br>
I hope that helps.<br>
<br>
Best,<br>
<br>
Alex<br>
</blockquote></div><br></div>