<html><head><meta http-equiv="Content-Type" content="text/html charset=iso-8859-1"><base href="x-msg://18526/"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On May 22, 2012, at 8:05 AM, "Medic, Vladimir" <<a href="mailto:vmedic@mips.com">vmedic@mips.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div ocsi="0" fpstyle="1" style="font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><div style="direction: ltr; font-family: Tahoma; font-size: 10pt; ">I'm trying to implement the standalone assembler for mips and I have encountered a problem in instruction operands matcher.<br>In mips instruction set there are math instructions with two format flags in the mnemonic, one for source and one for destination register.<br>For example<span class="Apple-converted-space"> </span><span style="font-family: 'Courier New'; ">ceil.w.s</span><span class="Apple-converted-space"> </span>means both source and destination are F32 registers while<span style="font-family: 'Courier New'; "><span class="Apple-converted-space"> </span>ceil.l.d<span class="Apple-converted-space"> </span></span>means both source and destination are F64 registers. Also, depending on the floating point unit configuration F64 may be either single 64 bit register or a pair of 32 bit registers. In the current implementation this instruction is defined as follows:<br><br><span style="font-family: 'Courier New'; ">// Instructions that convert an FP value to 64-bit fixed point.</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">let Predicates = [IsFP64bit], DecoderNamespace = "Mips64" in</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">multiclass FFR1_L_M<bits<6> funct, string opstr> {</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">  def _S   : FFR1<funct, 16, opstr, "l.s", FGR64, FGR32>;</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">  def _D64 : FFR1<funct, 17, opstr, "l.d", FGR64, FGR64>;</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">}</span><br style="font-family: 'Courier New'; "><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">// Instructions that convert an FP value to 32-bit fixed point.</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">multiclass FFR1_W_M<bits<6> funct, string opstr> {</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">  def _S   : FFR1<funct, 16, opstr, "w.s", FGR32, FGR32>;</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">  def _D32 : FFR1<funct, 17, opstr, "w.d", FGR32, AFGR64>,</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">             Requires<[NotFP64bit]>;</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">  def _D64 : FFR1<funct, 17, opstr, "w.d", FGR32, FGR64>,</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">             Requires<[IsFP64bit]> {</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">    let DecoderNamespace = "Mips64";</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">  }</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">}</span><br style="font-family: 'Courier New'; "><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">defm CEIL_W  : FFR1_W_M<0xe, "ceil">;</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">defm CEIL_L  : FFR1_L_M<0xa, "ceil">;</span><br><br>When assembly matcher is generated these are created as five instructions, each having 'ceil' as mnemonic:<br><br><span style="font-family: 'Courier New'; ">static const MatchEntry MatchTable[277] = {</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">.</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">.</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">.</span><br style="font-family: 'Courier New'; "><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; "> { Mips::CEIL_L_D64, 93 /* ceil */, Convert__Reg1_2__Reg1_3, { MCK__DOT_l, MCK__DOT_d, MCK_FGR64, MCK_FGR64 }, Feature_IsFP64bit, 0},</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">  { Mips::CEIL_L_S, 93 /* ceil */, Convert__Reg1_2__Reg1_3, { MCK__DOT_l, MCK__DOT_s, MCK_FGR64, MCK_FGR32 }, Feature_IsFP64bit, 0},</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">  { Mips::CEIL_W_D64, 93 /* ceil */, Convert__Reg1_2__Reg1_3, { MCK__DOT_w, MCK__DOT_d, MCK_FGR32, MCK_FGR64 }, Feature_IsFP64bit, 0},</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">  { Mips::CEIL_W_D32, 93 /* ceil */, Convert__Reg1_2__Reg1_3, { MCK__DOT_w, MCK__DOT_d, MCK_FGR32, MCK_AFGR64 }, Feature_NotFP64bit, 0},</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">  { Mips::CEIL_W_S, 93 /* ceil */, Convert__Reg1_2__Reg1_3, { MCK__DOT_w, MCK__DOT_s, MCK_FGR32, MCK_FGR32 }, 0, 0},</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">.</span><br style="font-family: 'Courier New'; "></div></div></blockquote><div><br></div><div>Note the "MCK_DOT_l" and "MCK_DOT_d" entries there. The matcher is expect those to be in the operand list as explicit token operands. Your parser will initially get the mnemonic, including those suffices as a single string, most likely. That will need to be manually split into its components so that the base mnemonic and the suffices are distinct for the matcher. ARM does similar things. I suggest looking there an example of how this might be done. Avert your eyes from some of the other horrible hackery in that function, though. ;)</div><div><br></div><div>-Jim</div><br><blockquote type="cite"><div ocsi="0" fpstyle="1" style="font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><div style="direction: ltr; font-family: Tahoma; font-size: 10pt; "><span style="font-family: 'Courier New'; ">.</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">.</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">}</span><br><br>So, when the MatchInstructionImpl is called it seems to look for a pair of instructions that match the mnemonic:<br><br><span style="font-family: 'Courier New'; "> // Search the table.</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">  std::pair<const MatchEntry*, const MatchEntry*> MnemonicRange =</span><br style="font-family: 'Courier New'; "><span style="font-family: 'Courier New'; ">    std::equal_range(MatchTable, MatchTable+277, Mnemonic, LessOpcode());</span><br><br>The search will always end in first two entries (<span class="Apple-converted-space"> </span><span style="font-family: 'Courier New'; ">Mips::CEIL_L_D64 and Mips::CEIL_L_S</span>) thus reporting the 'invalid operand' error when<span style="font-family: 'Courier New'; "><span class="Apple-converted-space"> </span>ceil.w.x<span class="Apple-converted-space"> </span></span>instruction is parsed.<br>Is there a way to direct this search somehow, maybe to use available features or we should change the definition of the instructions to have at least one format included in mnemonic?<br><br>Kind regards,<br>Vladimir<br></div>_______________________________________________<br>LLVM Developers mailing list<br><a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a><span class="Apple-converted-space"> </span>        <a href="http://llvm.cs.uiuc.edu">http://llvm.cs.uiuc.edu</a><br><a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br></div></blockquote></div><br></body></html>