• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "assembler/asm_assembler.h"
17 #include <unistd.h>
18 #include <securec.h>
19 #include "dwarf.h"
20 
21 namespace assembler {
InitialFileInfo(const std::string & inputFileName)22 void AsmAssembler::InitialFileInfo(const std::string &inputFileName)
23 {
24     std::string curDirName = get_current_dir_name();
25     assert(curDirName != "" && "InitialFileInfo: curDirName is nullptr");
26     std::string path(curDirName);
27     std::string cgFile(path.append("/mplcg"));
28     EmitComment(cgFile);
29     EmitComment("Compiling");
30     EmitComment("Be options");
31 
32     path = curDirName;
33     (void)path.append("/").append(inputFileName);
34     std::string irFile("\"");
35     (void)irFile.append(path).append("\"");
36     EmitDirective(kFile);
37     Emit(irFile);
38     Emit("\n");
39 }
40 
EmitFunctionHeader(int64 symIdx,SymbolAttr funcAttr,const std::string * secName)41 void AsmAssembler::EmitFunctionHeader(int64 symIdx, SymbolAttr funcAttr, const std::string *secName)
42 {
43     if (secName != nullptr) {
44         EmitDirective(kSection);
45         Emit(*secName);
46         Emit(",\"ax\",@progbits\n");
47     } else {
48         EmitSectionDirective(kSText);
49     }
50     EmitDirective(kAlign, 0, false, k8Bits);
51 
52     EmitSymbolAttrDirective(funcAttr, symIdx);
53 
54     EmitDirective(kFuncType, symIdx);
55     EmitDirective(kName, symIdx);
56     Emit("\t.cfi_startproc\n");
57 }
58 
EmitBBLabel(int64 labelSymIdx,bool genVerboseInfo,uint32 freq,const std::string * mirName)59 void AsmAssembler::EmitBBLabel(int64 labelSymIdx, bool genVerboseInfo, uint32 freq, const std::string *mirName)
60 {
61     std::string bbLabel = GetNameFromSymMap(labelSymIdx);
62     if (genVerboseInfo) {
63         Emit("//  freq:");
64         Emit(freq);
65         Emit("\n");
66 
67         Emit(bbLabel);
68         Emit(":");
69         if (mirName != nullptr) {
70             Emit("\t//  MIR: @");
71             Emit(*mirName);
72         }
73         Emit("\n");
74     } else {
75         EmitDirective(kName, labelSymIdx);
76     }
77 }
78 
EmitFunctionFoot(int64 symIdx,SymbolAttr funcAttr)79 void AsmAssembler::EmitFunctionFoot(int64 symIdx, SymbolAttr funcAttr)
80 {
81     (void)funcAttr;
82     Emit("\t.cfi_endproc\n");
83     EmitDirective(kSize, symIdx);
84     Emit("\n");
85 }
86 
PostEmitVariable(int64 symIdx,SymbolAttr symAttr,uint64 sizeInByte,bool belongsToTextSec)87 void AsmAssembler::PostEmitVariable(int64 symIdx, SymbolAttr symAttr, uint64 sizeInByte, bool belongsToTextSec)
88 {
89     (void)sizeInByte;
90     bool isLocal = false;
91     if (symAttr == kSALocal) {
92         isLocal = true;
93     }
94     EmitDirective(kSize, symIdx, isLocal);
95     Emit("\n");
96 }
97 
EmitFloatValue(int64 symIdx,int64 value,size_t valueSize)98 void AsmAssembler::EmitFloatValue(int64 symIdx, int64 value, size_t valueSize)
99 {
100     (void)symIdx;
101     EmitSizeDirective(valueSize, value, false, true);
102 }
103 
EmitJmpTableElem(int64 jmpLabelIdx,const std::vector<int64> & labelIdxs)104 void AsmAssembler::EmitJmpTableElem(int64 jmpLabelIdx, const std::vector<int64> &labelIdxs)
105 {
106     EmitDirective(kAlign, 0, false, k8Bits);
107     EmitDirective(kName, jmpLabelIdx);
108     for (int64 labelIdx : labelIdxs) {
109         EmitSizeDirective(k8Bytes, labelIdx, true);
110     }
111 }
112 
EmitVariable(int64 symIdx,uint64 sizeInByte,uint8 alignInByte,SymbolAttr symAttr,SectionKind sectionKind)113 void AsmAssembler::EmitVariable(int64 symIdx, uint64 sizeInByte, uint8 alignInByte, SymbolAttr symAttr,
114                                 SectionKind sectionKind)
115 {
116     bool isLocal = false;
117     if (symAttr == kSALocal) {
118         isLocal = true;
119     }
120 
121     if (sectionKind == kSComm || sectionKind == kSBss) {
122         EmitSectionDirective(kSData);
123         EmitSymbolAttrDirective(symAttr, symIdx, isLocal);
124         EmitDirective(kAlign, 0, isLocal, alignInByte);
125         Emit("\t.comm\t");
126         std::string name = GetNameFromSymMap(symIdx, isLocal);
127         Emit(name);
128         Emit(", ");
129         Emit(sizeInByte);
130         Emit(", ");
131         Emit(alignInByte);
132         Emit("\n");
133     } else {
134         EmitDirective(kObjType, symIdx, isLocal);
135         EmitSectionDirective(sectionKind);
136         EmitSymbolAttrDirective(symAttr, symIdx, isLocal);
137         EmitDirective(kAlign, 0, isLocal, alignInByte);
138         EmitDirective(kName, symIdx, isLocal);
139     }
140 }
141 
EmitDirectString(const std::string & ustr,bool belongsToDataSec,int64 strSymIdx,bool emitAscii)142 void AsmAssembler::EmitDirectString(const std::string &ustr, bool belongsToDataSec, int64 strSymIdx, bool emitAscii)
143 {
144     (void)belongsToDataSec;
145     if (strSymIdx != 0) {
146         EmitSectionDirective(kSData);
147         EmitDirective(kAlign, 0, false, k8Bits);
148         EmitDirective(kName, strSymIdx);
149     }
150 
151     if (emitAscii) {
152         Emit("\t.ascii\t\"");
153     } else {
154         Emit("\t.string\t\"");
155     }
156 
157     const char *str = ustr.c_str();
158     size_t len = ustr.size();
159     /* Rewrite special char with \\ */
160     for (size_t i = 0; i < len; i++) {
161         /* Referred to GNU AS: 3.6.1.1 Strings */
162         constexpr int kBufSize = 5;
163         constexpr int kFirstChar = 0;
164         constexpr int kSecondChar = 1;
165         constexpr int kThirdChar = 2;
166         constexpr int kLastChar = 4;
167         char buf[kBufSize];
168         if (isprint(*str)) {
169             buf[kFirstChar] = *str;
170             buf[kSecondChar] = 0;
171             if (*str == '\\' || *str == '\"') {
172                 buf[kFirstChar] = '\\';
173                 buf[kSecondChar] = *str;
174                 buf[kThirdChar] = 0;
175             }
176             Emit(buf);
177         } else if (*str == '\b') {
178             Emit("\\b");
179         } else if (*str == '\n') {
180             Emit("\\n");
181         } else if (*str == '\r') {
182             Emit("\\r");
183         } else if (*str == '\t') {
184             Emit("\\t");
185         } else if (*str == '\0') {
186             buf[kFirstChar] = '\\';
187             buf[kSecondChar] = '0';
188             buf[kThirdChar] = 0;
189             Emit(buf);
190         } else {
191             /* all others, print as number */
192             (void)snprintf_s(buf, sizeof(buf), 4, "\\%03o", (*str) & 0xFF); /* 4: max store chars */
193             buf[kLastChar] = '\0';
194             Emit(buf);
195         }
196         str++;
197     }
198     Emit("\"\n");
199 }
200 
EmitIndirectString(int64 strSymIdx,bool belongsToDataSec)201 void AsmAssembler::EmitIndirectString(int64 strSymIdx, bool belongsToDataSec)
202 {
203     (void)belongsToDataSec;
204     EmitSizeDirective(k8Bytes, strSymIdx, true);
205 }
206 
EmitIntValue(int64 value,size_t elemSize,bool belongsToDataSec)207 void AsmAssembler::EmitIntValue(int64 value, size_t elemSize, bool belongsToDataSec)
208 {
209     (void)belongsToDataSec;
210     EmitSizeDirective(elemSize, value, false);
211 }
212 
EmitAddrValue(int64 symIdx,int32 symAddrOfs,int32 structFieldOfs,bool belongsToDataSec)213 void AsmAssembler::EmitAddrValue(int64 symIdx, int32 symAddrOfs, int32 structFieldOfs, bool belongsToDataSec)
214 {
215     (void)belongsToDataSec;
216     Emit("\t.quad\t");
217     std::string name = GetNameFromSymMap(symIdx);
218     Emit(name);
219     if (symAddrOfs != 0) {
220         Emit(" + ");
221         Emit(symAddrOfs);
222     }
223     if (structFieldOfs != 0) {
224         Emit(" + ");
225         Emit(structFieldOfs);
226     }
227     Emit("\n");
228 }
229 
EmitAddrOfFuncValue(int64 symIdx,bool belongsToDataSec)230 void AsmAssembler::EmitAddrOfFuncValue(int64 symIdx, bool belongsToDataSec)
231 {
232     (void)belongsToDataSec;
233     EmitSizeDirective(k8Bytes, symIdx, true);
234 }
235 
EmitLabelValue(int64 symIdx,bool belongsToDataSec)236 void AsmAssembler::EmitLabelValue(int64 symIdx, bool belongsToDataSec)
237 {
238     (void)belongsToDataSec;
239     EmitSizeDirective(k8Bytes, symIdx, true);
240 }
241 
EmitBitFieldValue(uint64 combineBitFieldValue,bool belongsToDataSec)242 void AsmAssembler::EmitBitFieldValue(uint64 combineBitFieldValue, bool belongsToDataSec)
243 {
244     (void)belongsToDataSec;
245     EmitSizeDirective(k1Byte, combineBitFieldValue, false);
246 }
247 
248 /* emit debug info */
EmitHexUnsigned(uint64 num)249 void AsmAssembler::EmitHexUnsigned(uint64 num)
250 {
251     std::ios::fmtflags flag(this->outStream.flags());
252     this->outStream << "0x" << std::hex << num;
253     (void)this->outStream.flags(flag);
254 }
255 
EmitDecUnsigned(uint64 num)256 void AsmAssembler::EmitDecUnsigned(uint64 num)
257 {
258     std::ios::fmtflags flag(outStream.flags());
259     outStream << std::dec << num;
260     (void)outStream.flags(flag);
261 }
262 
EmitDecSigned(int64 num)263 void AsmAssembler::EmitDecSigned(int64 num)
264 {
265     std::ios::fmtflags flag(outStream.flags());
266     outStream << std::dec << num;
267     (void)outStream.flags(flag);
268 }
269 
EmitDIHeader()270 void AsmAssembler::EmitDIHeader()
271 {
272     Emit("\t.section ." + std::string("c_text") + ",\"ax\"\n");
273     Emit(".L" XSTR(TEXT_BEGIN) ":\n");
274 }
275 
EmitDIFooter()276 void AsmAssembler::EmitDIFooter()
277 {
278     Emit("\t.section ." + std::string("c_text") + ",\"ax\"\n");
279     Emit(".L" XSTR(TEXT_END) ":\n");
280 }
281 
EmitDIHeaderFileInfo()282 void AsmAssembler::EmitDIHeaderFileInfo()
283 {
284     Emit("// dummy header file 1\n");
285     Emit("// dummy header file 2\n");
286     Emit("// dummy header file 3\n");
287 }
288 
EmitDIDebugInfoSectionHeader(uint64 debugInfoLength)289 void AsmAssembler::EmitDIDebugInfoSectionHeader(uint64 debugInfoLength)
290 {
291     /* From DWARF Standard Specification V4. 7.5.1
292        collect section size */
293     Emit("\t.section\t.debug_info,\"\",@progbits\n");
294     /* label to mark start of the .debug_info section */
295     Emit(".L" XSTR(DEBUG_INFO_0) ":\n");
296     /* $ 7.5.1.1 */
297     Emit("\t.4byte\t");
298     EmitHexUnsigned(debugInfoLength);
299     Emit(CMNT "section length\n");
300     /* DWARF version. uhalf. */
301     Emit("\t.2byte\t");
302     /* 4 for version 4. */
303     EmitHexUnsigned(kDwarfVersion);
304     Emit("\n");
305     /* debug_abbrev_offset. 4byte for 32-bit, 8byte for 64-bit */
306     Emit("\t.4byte\t.L" XSTR(DEBUG_ABBREV_0) "\n");
307     /* address size. ubyte */
308     Emit("\t.byte\t");
309     EmitHexUnsigned(kSizeOfPTR);
310     Emit("\n");
311 }
312 
EmitDIDebugInfoSectionAbbrevId(bool verbose,uint32 abbrevId,const std::string & dieTagName,uint32 offset,uint32 size)313 void AsmAssembler::EmitDIDebugInfoSectionAbbrevId(bool verbose, uint32 abbrevId, const std::string &dieTagName,
314                                                   uint32 offset, uint32 size)
315 {
316     if (verbose) {
317         Emit("\n");
318     }
319     Emit("\t.uleb128 ");
320     EmitHexUnsigned(abbrevId);
321     if (verbose) {
322         Emit(CMNT);
323         Emit(dieTagName);
324         Emit(" Offset= ");
325         EmitHexUnsigned(offset);
326         Emit(" (");
327         EmitDecUnsigned(offset);
328         Emit(" ),  Size= ");
329         EmitHexUnsigned(size);
330         Emit(" (");
331         EmitDecUnsigned(size);
332         Emit(" )\n");
333     } else {
334         Emit("\n");
335     }
336 }
337 
EmitDIFormSpecification(unsigned int dwform)338 void AsmAssembler::EmitDIFormSpecification(unsigned int dwform)
339 {
340     Emit("\t");
341     switch (dwform) {
342         case DW_FORM_string:
343             Emit(".string");
344             break;
345         case DW_FORM_strp:
346         case DW_FORM_data4:
347         case DW_FORM_ref4:
348             Emit(".4byte   ");
349             break;
350         case DW_FORM_data1:
351             Emit(".byte    ");
352             break;
353         case DW_FORM_data2:
354             Emit(".2byte   ");
355             break;
356         case DW_FORM_data8:
357             Emit(".8byte   ");
358             break;
359         case DW_FORM_sec_offset:
360             Emit(".4byte   ");
361             break;
362             /* if DWARF64, should be .8byte? */
363         case DW_FORM_addr: /* Should we use DWARF64? for now, we generate .8byte as gcc does for DW_FORM_addr */
364             Emit(".8byte   ");
365             break;
366         case DW_FORM_exprloc:
367             Emit(".uleb128 ");
368             break;
369         default:
370             assert(0 && "NYI");
371             break;
372     }
373 }
374 
EmitDwFormString(const std::string & name)375 void AsmAssembler::EmitDwFormString(const std::string &name)
376 {
377     Emit("\"");
378     Emit(name);
379     Emit("\"");
380     Emit(CMNT "len = ");
381     EmitDecUnsigned(name.length() + 1);
382 }
383 
EmitDwFormStrp(uint32 strLabelId,size_t strTableSize)384 void AsmAssembler::EmitDwFormStrp(uint32 strLabelId, size_t strTableSize)
385 {
386     Emit(".L" XSTR(DEBUG_STR_LABEL));
387     outStream << strLabelId;
388 }
389 
EmitDwFormData(int32 attrValue,uint8 sizeInByte)390 void AsmAssembler::EmitDwFormData(int32 attrValue, uint8 sizeInByte)
391 {
392     EmitHexUnsigned(attrValue);
393 }
394 
EmitDwFormData8()395 void AsmAssembler::EmitDwFormData8()
396 {
397     Emit(".L" XSTR(TEXT_END) "-.L" XSTR(TEXT_BEGIN));
398 }
399 
EmitDwFormData8(uint32 endLabelFuncPuIdx,uint32 startLabelFuncPuIdx,uint32 endLabelIdx,uint32 startLabelIdx)400 void AsmAssembler::EmitDwFormData8(uint32 endLabelFuncPuIdx, uint32 startLabelFuncPuIdx, uint32 endLabelIdx,
401                                    uint32 startLabelIdx)
402 {
403     outStream << ".L." << endLabelFuncPuIdx << "__" << endLabelIdx;
404     Emit("-");
405     outStream << ".L." << startLabelFuncPuIdx << "__" << startLabelIdx;
406 }
407 
EmitLabel(uint32 funcPuIdx,uint32 labIdx)408 void AsmAssembler::EmitLabel(uint32 funcPuIdx, uint32 labIdx)
409 {
410     outStream << ".L." << funcPuIdx << "__" << labIdx;
411 }
412 
EmitDwFormSecOffset()413 void AsmAssembler::EmitDwFormSecOffset()
414 {
415     Emit(".L");
416     Emit(XSTR(DEBUG_LINE_0));
417 }
418 
EmitDwFormAddr(bool emitTextBegin)419 void AsmAssembler::EmitDwFormAddr(bool emitTextBegin)
420 {
421     if (emitTextBegin) {
422         Emit(".L" XSTR(TEXT_BEGIN));
423     } else {
424         Emit("XXX--ADDR--XXX");
425     }
426 }
427 
EmitDwFormRef4(uint64 offsetOrValue,bool unknownType,bool emitOffset)428 void AsmAssembler::EmitDwFormRef4(uint64 offsetOrValue, bool unknownType, bool emitOffset)
429 {
430     if (emitOffset) {
431         Emit(" OFFSET ");
432     }
433     EmitHexUnsigned(offsetOrValue);
434     if (unknownType) {
435         Emit(CMNT "Warning: dummy type used");
436     }
437 }
438 
EmitDwFormExprlocCfa(uint32 dwOp)439 void AsmAssembler::EmitDwFormExprlocCfa(uint32 dwOp)
440 {
441     EmitHexUnsigned(1);
442     Emit("\n\t.byte    ");
443     EmitHexUnsigned(dwOp);
444 }
445 
EmitDwFormExprlocAddr(uint32 dwOp,const std::string & addrStr)446 void AsmAssembler::EmitDwFormExprlocAddr(uint32 dwOp, const std::string &addrStr)
447 {
448     EmitHexUnsigned(k9ByteSize);
449     Emit("\n\t.byte    ");
450     EmitHexUnsigned(dwOp);
451     Emit("\n\t.8byte   ");
452     Emit(addrStr);
453 }
454 
EmitDwFormExprlocFbreg(uint32 dwOp,int fboffset,size_t sleb128Size)455 void AsmAssembler::EmitDwFormExprlocFbreg(uint32 dwOp, int fboffset, size_t sleb128Size)
456 {
457     EmitHexUnsigned(1 + sleb128Size);
458     Emit(CMNT "uleb128 size");
459     Emit("\n\t.byte    ");
460     EmitHexUnsigned(dwOp);
461     Emit("\n\t.sleb128 ");
462     EmitDecSigned(fboffset);
463 }
464 
EmitDwFormExprlocBregn(uint32 dwOp,const std::string & dwOpName)465 void AsmAssembler::EmitDwFormExprlocBregn(uint32 dwOp, const std::string &dwOpName)
466 {
467     EmitHexUnsigned(k2Bytes);
468     Emit(CMNT "size");
469     Emit("\n\t.byte    ");
470     EmitHexUnsigned(dwOp);
471     Emit(CMNT);
472     Emit(dwOpName);
473     Emit("\n\t.sleb128 ");
474     EmitDecSigned(0);
475     Emit(CMNT "offset");
476 }
477 
EmitDwFormExprloc(uintptr elp)478 void AsmAssembler::EmitDwFormExprloc(uintptr elp)
479 {
480     EmitHexUnsigned(elp);
481 }
482 
EmitDIDwName(const std::string & dwAtName,const std::string & dwForName)483 void AsmAssembler::EmitDIDwName(const std::string &dwAtName, const std::string &dwForName)
484 {
485     Emit(CMNT);
486     Emit(dwAtName);
487     Emit(" : ");
488     Emit(dwForName);
489 }
490 
EmitDIDebugAbbrevDiae(bool verbose,uint32 abbrevId,uint32 tag,const std::string & dwTagName,bool withChildren)491 void AsmAssembler::EmitDIDebugAbbrevDiae(bool verbose, uint32 abbrevId, uint32 tag, const std::string &dwTagName,
492                                          bool withChildren)
493 {
494     if (verbose) {
495         Emit("\n");
496     }
497     Emit("\t.uleb128 ");
498     EmitHexUnsigned(abbrevId);
499     if (verbose) {
500         Emit(CMNT "Abbrev Entry ID");
501     }
502     Emit("\n");
503     /* TAG */
504     Emit("\t.uleb128 ");
505     EmitHexUnsigned(tag);
506     if (verbose) {
507         Emit(CMNT);
508         Emit(dwTagName);
509     }
510     Emit("\n");
511     /* children? */
512     Emit("\t.byte    ");
513     EmitHexUnsigned(static_cast<uint64>(withChildren));
514     if (verbose) {
515         Emit(withChildren ? CMNT "DW_CHILDREN_yes" : CMNT "DW_CHILDREN_no");
516     }
517     Emit("\n");
518 }
519 
EmitDIDebugAbbrevDiaePairItem(bool verbose,uint32 aplAt,uint32 aplFrom,const std::string & dwAtName,const std::string & dwFromName)520 void AsmAssembler::EmitDIDebugAbbrevDiaePairItem(bool verbose, uint32 aplAt, uint32 aplFrom,
521                                                  const std::string &dwAtName, const std::string &dwFromName)
522 {
523     /* odd entry -- DW_AT_*, even entry -- DW_FORM_* */
524     Emit("\t.uleb128 ");
525     EmitHexUnsigned(aplAt);
526     if (verbose) {
527         Emit(CMNT);
528         Emit(dwAtName);
529     }
530     Emit("\n");
531     Emit("\t.uleb128 ");
532     EmitHexUnsigned(aplFrom);
533     if (verbose) {
534         Emit(CMNT);
535         Emit(dwFromName);
536     }
537     Emit("\n");
538 }
539 
EmitDIDebugStrSection(const std::vector<uint32> & strps,const std::vector<std::string> & debugStrs,uint64 size,size_t strTableSize)540 void AsmAssembler::EmitDIDebugStrSection(const std::vector<uint32> &strps, const std::vector<std::string> &debugStrs,
541                                          uint64 size, size_t strTableSize)
542 {
543     Emit("\t.section\t.debug_str,\"MS\",@progbits,1\n");
544     for (int i = 0; i < static_cast<int>(debugStrs.size()); i++) {
545         Emit(".L" XSTR(DEBUG_STR_LABEL));
546         this->outStream << strps[i];
547         Emit(":\n");
548         Emit("\t.string \"");
549         Emit(debugStrs[i]);
550         Emit("\"\n");
551     }
552 }
553 
EmitNull(uint64 sizeInByte)554 void AsmAssembler::EmitNull(uint64 sizeInByte)
555 {
556     EmitDirective(kZero);
557     Emit(sizeInByte);
558     Emit("\n");
559 }
560 
561 /* start of X64 instructions */
562 /* mov */
Mov(InsnSize insnSize,Reg srcReg,Reg destReg)563 void AsmAssembler::Mov(InsnSize insnSize, Reg srcReg, Reg destReg)
564 {
565     Emit("\tmov");
566     EmitInsnSuffix(insnSize);
567     Emit("\t");
568     EmitRegReg(srcReg, destReg);
569     Emit("\n");
570 }
571 
Mov(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)572 void AsmAssembler::Mov(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
573 {
574     Emit("\tmov");
575     EmitInsnSuffix(insnSize);
576     Emit("\t");
577     EmitImmOrSymbolReg(immOpnd.first, immOpnd.second, reg);
578     Emit("\n");
579 }
580 
Mov(InsnSize insnSize,const Mem & mem,Reg reg)581 void AsmAssembler::Mov(InsnSize insnSize, const Mem &mem, Reg reg)
582 {
583     Emit("\tmov");
584     EmitInsnSuffix(insnSize);
585     Emit("\t");
586     EmitMemReg(mem, reg);
587     Emit("\n");
588 }
589 
Mov(InsnSize insnSize,Reg reg,const Mem & mem)590 void AsmAssembler::Mov(InsnSize insnSize, Reg reg, const Mem &mem)
591 {
592     Emit("\tmov");
593     EmitInsnSuffix(insnSize);
594     Emit("\t");
595     EmitRegMem(reg, mem);
596     Emit("\n");
597 }
598 
Mov(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)599 void AsmAssembler::Mov(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
600 {
601     Emit("\tmov");
602     EmitInsnSuffix(insnSize);
603     Emit("\t");
604     EmitImmOrSymbolMem(immOpnd.first, immOpnd.second, mem);
605     Emit("\n");
606 }
607 
608 /* floating point mov */
Mov(Reg srcReg,Reg destReg,bool isMovD)609 void AsmAssembler::Mov(Reg srcReg, Reg destReg, bool isMovD)
610 {
611     if (isMovD) {
612         Emit("\tmovd\t");
613     } else {
614         Emit("\tmovq\t");
615     }
616     EmitRegReg(srcReg, destReg);
617     Emit("\n");
618 }
619 
MovF(const Mem & mem,Reg reg,bool isSingle)620 void AsmAssembler::MovF(const Mem &mem, Reg reg, bool isSingle)
621 {
622     if (isSingle) {
623         Emit("\tmovss\t");
624     } else {
625         Emit("\tmovsd\t");
626     }
627     EmitMemReg(mem, reg);
628     Emit("\n");
629 }
630 
MovF(Reg reg,const Mem & mem,bool isSingle)631 void AsmAssembler::MovF(Reg reg, const Mem &mem, bool isSingle)
632 {
633     if (isSingle) {
634         Emit("\tmovss\t");
635     } else {
636         Emit("\tmovsd\t");
637     }
638     EmitRegMem(reg, mem);
639     Emit("\n");
640 }
641 
642 /* movabs */
Movabs(const ImmOpnd & immOpnd,Reg reg)643 void AsmAssembler::Movabs(const ImmOpnd &immOpnd, Reg reg)
644 {
645     Emit("\tmovabs");
646     Emit("\t");
647     EmitImmOrSymbolReg(immOpnd.first, immOpnd.second, reg);
648     Emit("\n");
649 }
650 
Movabs(int64 symIdx,Reg reg)651 void AsmAssembler::Movabs(int64 symIdx, Reg reg)
652 {
653     Emit("\tmovabs");
654     Emit("\t");
655     EmitLabelReg(symIdx, reg);
656     Emit("\n");
657 }
658 
659 /* push */
Push(InsnSize insnSize,Reg reg)660 void AsmAssembler::Push(InsnSize insnSize, Reg reg)
661 {
662     Emit("\tpush");
663     EmitInsnSuffix(insnSize);
664     Emit("\t");
665     EmitReg(reg);
666     Emit("\n");
667 }
668 
669 /* pop */
Pop(InsnSize insnSize,Reg reg)670 void AsmAssembler::Pop(InsnSize insnSize, Reg reg)
671 {
672     Emit("\tpop");
673     EmitInsnSuffix(insnSize);
674     Emit("\t");
675     EmitReg(reg);
676     Emit("\n");
677 }
678 
679 /* lea */
Lea(InsnSize insnSize,const Mem & mem,Reg reg)680 void AsmAssembler::Lea(InsnSize insnSize, const Mem &mem, Reg reg)
681 {
682     Emit("\tlea");
683     EmitInsnSuffix(insnSize);
684     Emit("\t");
685     EmitMemReg(mem, reg);
686     Emit("\n");
687 }
688 
689 /* movzx */
MovZx(InsnSize sSize,InsnSize dSize,Reg srcReg,Reg destReg)690 void AsmAssembler::MovZx(InsnSize sSize, InsnSize dSize, Reg srcReg, Reg destReg)
691 {
692     Emit("\tmovz");
693     EmitInsnSuffix(sSize);
694     EmitInsnSuffix(dSize);
695     Emit("\t");
696     EmitRegReg(srcReg, destReg);
697     Emit("\n");
698 }
699 
MovZx(InsnSize sSize,InsnSize dSize,const Mem & mem,Reg reg)700 void AsmAssembler::MovZx(InsnSize sSize, InsnSize dSize, const Mem &mem, Reg reg)
701 {
702     Emit("\tmovz");
703     EmitInsnSuffix(sSize);
704     EmitInsnSuffix(dSize);
705     Emit("\t");
706     EmitMemReg(mem, reg);
707     Emit("\n");
708 }
709 
710 /* movsx */
MovSx(InsnSize sSize,InsnSize dSize,Reg srcReg,Reg destReg)711 void AsmAssembler::MovSx(InsnSize sSize, InsnSize dSize, Reg srcReg, Reg destReg)
712 {
713     Emit("\tmovs");
714     EmitInsnSuffix(sSize);
715     EmitInsnSuffix(dSize);
716     Emit("\t");
717     EmitRegReg(srcReg, destReg);
718     Emit("\n");
719 }
720 
MovSx(InsnSize sSize,InsnSize dSize,const Mem & mem,Reg reg)721 void AsmAssembler::MovSx(InsnSize sSize, InsnSize dSize, const Mem &mem, Reg reg)
722 {
723     Emit("\tmovs");
724     EmitInsnSuffix(sSize);
725     EmitInsnSuffix(dSize);
726     Emit("\t");
727     EmitMemReg(mem, reg);
728     Emit("\n");
729 }
730 
731 /* add */
Add(InsnSize insnSize,Reg srcReg,Reg destReg)732 void AsmAssembler::Add(InsnSize insnSize, Reg srcReg, Reg destReg)
733 {
734     Emit("\tadd");
735     EmitInsnSuffix(insnSize);
736     Emit("\t");
737     EmitRegReg(srcReg, destReg);
738     Emit("\n");
739 }
740 
Add(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)741 void AsmAssembler::Add(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
742 {
743     Emit("\tadd");
744     EmitInsnSuffix(insnSize);
745     Emit("\t");
746     EmitImmOrSymbolReg(immOpnd.first, immOpnd.second, reg);
747     Emit("\n");
748 }
749 
Add(InsnSize insnSize,const Mem & mem,Reg reg)750 void AsmAssembler::Add(InsnSize insnSize, const Mem &mem, Reg reg)
751 {
752     Emit("\tadd");
753     EmitInsnSuffix(insnSize);
754     Emit("\t");
755     EmitMemReg(mem, reg);
756     Emit("\n");
757 }
758 
Add(InsnSize insnSize,Reg reg,const Mem & mem)759 void AsmAssembler::Add(InsnSize insnSize, Reg reg, const Mem &mem)
760 {
761     Emit("\tadd");
762     EmitInsnSuffix(insnSize);
763     Emit("\t");
764     EmitRegMem(reg, mem);
765     Emit("\n");
766 }
767 
Add(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)768 void AsmAssembler::Add(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
769 {
770     Emit("\tadd");
771     EmitInsnSuffix(insnSize);
772     Emit("\t");
773     EmitImmOrSymbolMem(immOpnd.first, immOpnd.second, mem);
774     Emit("\n");
775 }
776 
777 /* add floating point */
Add(Reg srcReg,Reg destReg,bool isSingle)778 void AsmAssembler::Add(Reg srcReg, Reg destReg, bool isSingle)
779 {
780     if (isSingle) {
781         Emit("\taddss\t");
782     } else {
783         Emit("\taddsd\t");
784     }
785     EmitRegReg(srcReg, destReg);
786     Emit("\n");
787 }
788 
Add(const Mem & mem,Reg reg,bool isSingle)789 void AsmAssembler::Add(const Mem &mem, Reg reg, bool isSingle)
790 {
791     if (isSingle) {
792         Emit("\taddss\t");
793     } else {
794         Emit("\taddsd\t");
795     }
796     EmitMemReg(mem, reg);
797     Emit("\n");
798 }
799 
800 /* sub */
Sub(InsnSize insnSize,Reg srcReg,Reg destReg)801 void AsmAssembler::Sub(InsnSize insnSize, Reg srcReg, Reg destReg)
802 {
803     Emit("\tsub");
804     EmitInsnSuffix(insnSize);
805     Emit("\t");
806     EmitRegReg(srcReg, destReg);
807     Emit("\n");
808 }
809 
Sub(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)810 void AsmAssembler::Sub(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
811 {
812     Emit("\tsub");
813     EmitInsnSuffix(insnSize);
814     Emit("\t");
815     EmitImmOrSymbolReg(immOpnd.first, immOpnd.second, reg);
816     Emit("\n");
817 }
818 
Sub(InsnSize insnSize,const Mem & mem,Reg reg)819 void AsmAssembler::Sub(InsnSize insnSize, const Mem &mem, Reg reg)
820 {
821     Emit("\tsub");
822     EmitInsnSuffix(insnSize);
823     Emit("\t");
824     EmitMemReg(mem, reg);
825     Emit("\n");
826 }
827 
Sub(InsnSize insnSize,Reg reg,const Mem & mem)828 void AsmAssembler::Sub(InsnSize insnSize, Reg reg, const Mem &mem)
829 {
830     Emit("\tsub");
831     EmitInsnSuffix(insnSize);
832     Emit("\t");
833     EmitRegMem(reg, mem);
834     Emit("\n");
835 }
836 
Sub(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)837 void AsmAssembler::Sub(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
838 {
839     Emit("\tsub");
840     EmitInsnSuffix(insnSize);
841     Emit("\t");
842     EmitImmOrSymbolMem(immOpnd.first, immOpnd.second, mem);
843     Emit("\n");
844 }
845 
846 /* sub floating point */
Sub(Reg srcReg,Reg destReg,bool isSingle)847 void AsmAssembler::Sub(Reg srcReg, Reg destReg, bool isSingle)
848 {
849     if (isSingle) {
850         Emit("\tsubss\t");
851     } else {
852         Emit("\tsubsd\t");
853     }
854     EmitRegReg(srcReg, destReg);
855     Emit("\n");
856 }
857 
Sub(const Mem & mem,Reg reg,bool isSingle)858 void AsmAssembler::Sub(const Mem &mem, Reg reg, bool isSingle)
859 {
860     if (isSingle) {
861         Emit("\tsubss\t");
862     } else {
863         Emit("\tsubsd\t");
864     }
865     EmitMemReg(mem, reg);
866     Emit("\n");
867 }
868 
869 /* and */
And(InsnSize insnSize,Reg srcReg,Reg destReg)870 void AsmAssembler::And(InsnSize insnSize, Reg srcReg, Reg destReg)
871 {
872     Emit("\tand");
873     EmitInsnSuffix(insnSize);
874     Emit("\t");
875     EmitRegReg(srcReg, destReg);
876     Emit("\n");
877 }
878 
And(InsnSize insnSize,const Mem & mem,Reg reg)879 void AsmAssembler::And(InsnSize insnSize, const Mem &mem, Reg reg)
880 {
881     Emit("\tand");
882     EmitInsnSuffix(insnSize);
883     Emit("\t");
884     EmitMemReg(mem, reg);
885     Emit("\n");
886 }
887 
And(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)888 void AsmAssembler::And(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
889 {
890     Emit("\tand");
891     EmitInsnSuffix(insnSize);
892     Emit("\t");
893     EmitImmOrSymbolReg(immOpnd.first, immOpnd.second, reg);
894     Emit("\n");
895 }
896 
And(InsnSize insnSize,Reg reg,const Mem & mem)897 void AsmAssembler::And(InsnSize insnSize, Reg reg, const Mem &mem)
898 {
899     Emit("\tand");
900     EmitInsnSuffix(insnSize);
901     Emit("\t");
902     EmitRegMem(reg, mem);
903     Emit("\n");
904 }
905 
And(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)906 void AsmAssembler::And(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
907 {
908     Emit("\tand");
909     EmitInsnSuffix(insnSize);
910     Emit("\t");
911     EmitImmOrSymbolMem(immOpnd.first, immOpnd.second, mem);
912     Emit("\n");
913 }
914 
915 /* or */
Or(InsnSize insnSize,Reg srcReg,Reg destReg)916 void AsmAssembler::Or(InsnSize insnSize, Reg srcReg, Reg destReg)
917 {
918     Emit("\tor");
919     EmitInsnSuffix(insnSize);
920     Emit("\t");
921     EmitRegReg(srcReg, destReg);
922     Emit("\n");
923 }
924 
Or(InsnSize insnSize,const Mem & mem,Reg reg)925 void AsmAssembler::Or(InsnSize insnSize, const Mem &mem, Reg reg)
926 {
927     Emit("\tor");
928     EmitInsnSuffix(insnSize);
929     Emit("\t");
930     EmitMemReg(mem, reg);
931     Emit("\n");
932 }
933 
Or(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)934 void AsmAssembler::Or(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
935 {
936     Emit("\tor");
937     EmitInsnSuffix(insnSize);
938     Emit("\t");
939     EmitImmOrSymbolReg(immOpnd.first, immOpnd.second, reg);
940     Emit("\n");
941 }
942 
Or(InsnSize insnSize,Reg reg,const Mem & mem)943 void AsmAssembler::Or(InsnSize insnSize, Reg reg, const Mem &mem)
944 {
945     Emit("\tor");
946     EmitInsnSuffix(insnSize);
947     Emit("\t");
948     EmitRegMem(reg, mem);
949     Emit("\n");
950 }
951 
Or(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)952 void AsmAssembler::Or(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
953 {
954     Emit("\tor");
955     EmitInsnSuffix(insnSize);
956     Emit("\t");
957     EmitImmOrSymbolMem(immOpnd.first, immOpnd.second, mem);
958     Emit("\n");
959 }
960 
961 /* xor */
Xor(InsnSize insnSize,Reg srcReg,Reg destReg)962 void AsmAssembler::Xor(InsnSize insnSize, Reg srcReg, Reg destReg)
963 {
964     Emit("\txor");
965     EmitInsnSuffix(insnSize);
966     Emit("\t");
967     EmitRegReg(srcReg, destReg);
968     Emit("\n");
969 }
970 
Xor(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)971 void AsmAssembler::Xor(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
972 {
973     Emit("\txor");
974     EmitInsnSuffix(insnSize);
975     Emit("\t");
976     EmitImmOrSymbolReg(immOpnd.first, immOpnd.second, reg);
977     Emit("\n");
978 }
979 
Xor(InsnSize insnSize,const Mem & mem,Reg reg)980 void AsmAssembler::Xor(InsnSize insnSize, const Mem &mem, Reg reg)
981 {
982     Emit("\txor");
983     EmitInsnSuffix(insnSize);
984     Emit("\t");
985     EmitMemReg(mem, reg);
986     Emit("\n");
987 }
988 
Xor(InsnSize insnSize,Reg reg,const Mem & mem)989 void AsmAssembler::Xor(InsnSize insnSize, Reg reg, const Mem &mem)
990 {
991     Emit("\txor");
992     EmitInsnSuffix(insnSize);
993     Emit("\t");
994     EmitRegMem(reg, mem);
995     Emit("\n");
996 }
997 
Xor(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)998 void AsmAssembler::Xor(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
999 {
1000     Emit("\txor");
1001     EmitInsnSuffix(insnSize);
1002     Emit("\t");
1003     EmitImmOrSymbolMem(immOpnd.first, immOpnd.second, mem);
1004     Emit("\n");
1005 }
1006 
1007 /* not */
Not(InsnSize insnSize,Reg reg)1008 void AsmAssembler::Not(InsnSize insnSize, Reg reg)
1009 {
1010     Emit("\tnot");
1011     EmitInsnSuffix(insnSize);
1012     Emit("\t");
1013     EmitReg(reg);
1014     Emit("\n");
1015 }
1016 
Not(InsnSize insnSize,const Mem & mem)1017 void AsmAssembler::Not(InsnSize insnSize, const Mem &mem)
1018 {
1019     Emit("\tnot");
1020     EmitInsnSuffix(insnSize);
1021     Emit("\t");
1022     EmitMem(mem);
1023     Emit("\n");
1024 }
1025 
1026 /* neg */
Neg(InsnSize insnSize,Reg reg)1027 void AsmAssembler::Neg(InsnSize insnSize, Reg reg)
1028 {
1029     Emit("\tneg");
1030     EmitInsnSuffix(insnSize);
1031     Emit("\t");
1032     EmitReg(reg);
1033     Emit("\n");
1034 }
1035 
Neg(InsnSize insnSize,const Mem & mem)1036 void AsmAssembler::Neg(InsnSize insnSize, const Mem &mem)
1037 {
1038     Emit("\tneg");
1039     EmitInsnSuffix(insnSize);
1040     Emit("\t");
1041     EmitMem(mem);
1042     Emit("\n");
1043 }
1044 
1045 /* div & cwd, cdq, cqo */
Idiv(InsnSize insnSize,Reg reg)1046 void AsmAssembler::Idiv(InsnSize insnSize, Reg reg)
1047 {
1048     Emit("\tidiv");
1049     EmitInsnSuffix(insnSize);
1050     Emit("\t");
1051     EmitReg(reg);
1052     Emit("\n");
1053 }
1054 
Idiv(InsnSize insnSize,const Mem & mem)1055 void AsmAssembler::Idiv(InsnSize insnSize, const Mem &mem)
1056 {
1057     Emit("\tidiv");
1058     EmitInsnSuffix(insnSize);
1059     Emit("\t");
1060     EmitMem(mem);
1061     Emit("\n");
1062 }
1063 
Div(InsnSize insnSize,Reg reg)1064 void AsmAssembler::Div(InsnSize insnSize, Reg reg)
1065 {
1066     Emit("\tdiv");
1067     EmitInsnSuffix(insnSize);
1068     Emit("\t");
1069     EmitReg(reg);
1070     Emit("\n");
1071 }
1072 
Div(InsnSize insnSize,const Mem & mem)1073 void AsmAssembler::Div(InsnSize insnSize, const Mem &mem)
1074 {
1075     Emit("\tdiv");
1076     EmitInsnSuffix(insnSize);
1077     Emit("\t");
1078     EmitMem(mem);
1079     Emit("\n");
1080 }
1081 
Cwd()1082 void AsmAssembler::Cwd()
1083 {
1084     Emit("\tcwd\n");
1085 }
1086 
Cdq()1087 void AsmAssembler::Cdq()
1088 {
1089     Emit("\tcdq\n");
1090 }
1091 
Cqo()1092 void AsmAssembler::Cqo()
1093 {
1094     Emit("\tcqo\n");
1095 }
1096 
1097 /* shl */
Shl(InsnSize insnSize,Reg srcReg,Reg destReg)1098 void AsmAssembler::Shl(InsnSize insnSize, Reg srcReg, Reg destReg)
1099 {
1100     Emit("\tshl");
1101     EmitInsnSuffix(insnSize);
1102     Emit("\t");
1103     EmitRegReg(srcReg, destReg);
1104     Emit("\n");
1105 }
1106 
Shl(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1107 void AsmAssembler::Shl(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1108 {
1109     Emit("\tshl");
1110     EmitInsnSuffix(insnSize);
1111     Emit("\t");
1112     EmitImmOrSymbolReg(immOpnd.first, immOpnd.second, reg);
1113     Emit("\n");
1114 }
1115 
Shl(InsnSize insnSize,Reg reg,const Mem & mem)1116 void AsmAssembler::Shl(InsnSize insnSize, Reg reg, const Mem &mem)
1117 {
1118     Emit("\tshl");
1119     EmitInsnSuffix(insnSize);
1120     Emit("\t");
1121     EmitRegMem(reg, mem);
1122     Emit("\n");
1123 }
1124 
Shl(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1125 void AsmAssembler::Shl(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1126 {
1127     Emit("\tshl");
1128     EmitInsnSuffix(insnSize);
1129     Emit("\t");
1130     EmitImmOrSymbolMem(immOpnd.first, immOpnd.second, mem);
1131     Emit("\n");
1132 }
1133 
1134 /* sar */
Sar(InsnSize insnSize,Reg srcReg,Reg destReg)1135 void AsmAssembler::Sar(InsnSize insnSize, Reg srcReg, Reg destReg)
1136 {
1137     Emit("\tsar");
1138     EmitInsnSuffix(insnSize);
1139     Emit("\t");
1140     EmitRegReg(srcReg, destReg);
1141     Emit("\n");
1142 }
1143 
Sar(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1144 void AsmAssembler::Sar(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1145 {
1146     Emit("\tsar");
1147     EmitInsnSuffix(insnSize);
1148     Emit("\t");
1149     EmitImmOrSymbolReg(immOpnd.first, immOpnd.second, reg);
1150     Emit("\n");
1151 }
1152 
Sar(InsnSize insnSize,Reg reg,const Mem & mem)1153 void AsmAssembler::Sar(InsnSize insnSize, Reg reg, const Mem &mem)
1154 {
1155     Emit("\tsar");
1156     EmitInsnSuffix(insnSize);
1157     Emit("\t");
1158     EmitRegMem(reg, mem);
1159     Emit("\n");
1160 }
1161 
Sar(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1162 void AsmAssembler::Sar(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1163 {
1164     Emit("\tsar");
1165     EmitInsnSuffix(insnSize);
1166     Emit("\t");
1167     EmitImmOrSymbolMem(immOpnd.first, immOpnd.second, mem);
1168     Emit("\n");
1169 }
1170 
1171 /* shr */
Shr(InsnSize insnSize,Reg srcReg,Reg destReg)1172 void AsmAssembler::Shr(InsnSize insnSize, Reg srcReg, Reg destReg)
1173 {
1174     Emit("\tshr");
1175     EmitInsnSuffix(insnSize);
1176     Emit("\t");
1177     EmitRegReg(srcReg, destReg);
1178     Emit("\n");
1179 }
1180 
Shr(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1181 void AsmAssembler::Shr(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1182 {
1183     Emit("\tshr");
1184     EmitInsnSuffix(insnSize);
1185     Emit("\t");
1186     EmitImmOrSymbolReg(immOpnd.first, immOpnd.second, reg);
1187     Emit("\n");
1188 }
1189 
Shr(InsnSize insnSize,Reg reg,const Mem & mem)1190 void AsmAssembler::Shr(InsnSize insnSize, Reg reg, const Mem &mem)
1191 {
1192     Emit("\tshr");
1193     EmitInsnSuffix(insnSize);
1194     Emit("\t");
1195     EmitRegMem(reg, mem);
1196     Emit("\n");
1197 }
1198 
Shr(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1199 void AsmAssembler::Shr(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1200 {
1201     Emit("\tshr");
1202     EmitInsnSuffix(insnSize);
1203     Emit("\t");
1204     EmitImmOrSymbolMem(immOpnd.first, immOpnd.second, mem);
1205     Emit("\n");
1206 }
1207 
1208 /* jmp */
Jmp(Reg reg)1209 void AsmAssembler::Jmp(Reg reg)
1210 {
1211     Emit("\tjmp\t");
1212     Emit("*");
1213     EmitReg(reg);
1214     Emit("\n");
1215 }
1216 
Jmp(const Mem & mem)1217 void AsmAssembler::Jmp(const Mem &mem)
1218 {
1219     Emit("\tjmp\t");
1220     Emit("*");
1221     EmitMem(mem);
1222     Emit("\n");
1223 }
1224 
Jmp(int64 symIdx)1225 void AsmAssembler::Jmp(int64 symIdx)
1226 {
1227     Emit("\tjmp\t");
1228     EmitLabel(symIdx);
1229     Emit("\n");
1230 }
1231 
1232 /* jump condition */
Je(int64 symIdx)1233 void AsmAssembler::Je(int64 symIdx)
1234 {
1235     Emit("\tje\t");
1236     EmitLabel(symIdx);
1237     Emit("\n");
1238 }
1239 
Ja(int64 symIdx)1240 void AsmAssembler::Ja(int64 symIdx)
1241 {
1242     Emit("\tja\t");
1243     EmitLabel(symIdx);
1244     Emit("\n");
1245 }
1246 
Jae(int64 symIdx)1247 void AsmAssembler::Jae(int64 symIdx)
1248 {
1249     Emit("\tjae\t");
1250     EmitLabel(symIdx);
1251     Emit("\n");
1252 }
1253 
Jne(int64 symIdx)1254 void AsmAssembler::Jne(int64 symIdx)
1255 {
1256     Emit("\tjne\t");
1257     EmitLabel(symIdx);
1258     Emit("\n");
1259 }
1260 
Jb(int64 symIdx)1261 void AsmAssembler::Jb(int64 symIdx)
1262 {
1263     Emit("\tjb\t");
1264     EmitLabel(symIdx);
1265     Emit("\n");
1266 }
1267 
Jbe(int64 symIdx)1268 void AsmAssembler::Jbe(int64 symIdx)
1269 {
1270     Emit("\tjbe\t");
1271     EmitLabel(symIdx);
1272     Emit("\n");
1273 }
1274 
Jg(int64 symIdx)1275 void AsmAssembler::Jg(int64 symIdx)
1276 {
1277     Emit("\tjg\t");
1278     EmitLabel(symIdx);
1279     Emit("\n");
1280 }
1281 
Jge(int64 symIdx)1282 void AsmAssembler::Jge(int64 symIdx)
1283 {
1284     Emit("\tjge\t");
1285     EmitLabel(symIdx);
1286     Emit("\n");
1287 }
1288 
Jl(int64 symIdx)1289 void AsmAssembler::Jl(int64 symIdx)
1290 {
1291     Emit("\tjl\t");
1292     EmitLabel(symIdx);
1293     Emit("\n");
1294 }
1295 
Jle(int64 symIdx)1296 void AsmAssembler::Jle(int64 symIdx)
1297 {
1298     Emit("\tjle\t");
1299     EmitLabel(symIdx);
1300     Emit("\n");
1301 }
1302 
1303 /* cmp */
Cmp(InsnSize insnSize,Reg srcReg,Reg destReg)1304 void AsmAssembler::Cmp(InsnSize insnSize, Reg srcReg, Reg destReg)
1305 {
1306     Emit("\tcmp");
1307     EmitInsnSuffix(insnSize);
1308     Emit("\t");
1309     EmitRegReg(srcReg, destReg);
1310     Emit("\n");
1311 }
1312 
Cmp(InsnSize insnSize,const Mem & mem,Reg reg)1313 void AsmAssembler::Cmp(InsnSize insnSize, const Mem &mem, Reg reg)
1314 {
1315     Emit("\tcmp");
1316     EmitInsnSuffix(insnSize);
1317     Emit("\t");
1318     EmitMemReg(mem, reg);
1319     Emit("\n");
1320 }
1321 
Cmp(InsnSize insnSize,Reg reg,const Mem & mem)1322 void AsmAssembler::Cmp(InsnSize insnSize, Reg reg, const Mem &mem)
1323 {
1324     Emit("\tcmp");
1325     EmitInsnSuffix(insnSize);
1326     Emit("\t");
1327     EmitRegMem(reg, mem);
1328     Emit("\n");
1329 }
1330 
Cmp(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1331 void AsmAssembler::Cmp(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1332 {
1333     Emit("\tcmp");
1334     EmitInsnSuffix(insnSize);
1335     Emit("\t");
1336     EmitImmOrSymbolReg(immOpnd.first, immOpnd.second, reg);
1337     Emit("\n");
1338 }
1339 
Cmp(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1340 void AsmAssembler::Cmp(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1341 {
1342     Emit("\tcmp");
1343     EmitInsnSuffix(insnSize);
1344     Emit("\t");
1345     EmitImmOrSymbolMem(immOpnd.first, immOpnd.second, mem);
1346     Emit("\n");
1347 }
1348 
1349 /* test */
Test(InsnSize insnSize,Reg srcReg,Reg destReg)1350 void AsmAssembler::Test(InsnSize insnSize, Reg srcReg, Reg destReg)
1351 {
1352     Emit("\ttest");
1353     EmitInsnSuffix(insnSize);
1354     Emit("\t");
1355     EmitRegReg(srcReg, destReg);
1356     Emit("\n");
1357 }
1358 
1359 /* set */
Setbe(Reg reg)1360 void AsmAssembler::Setbe(Reg reg)
1361 {
1362     Emit("\tsetbe\t");
1363     EmitReg(reg);
1364     Emit("\n");
1365 }
1366 
Setbe(const Mem & mem)1367 void AsmAssembler::Setbe(const Mem &mem)
1368 {
1369     Emit("\tsetbe\t");
1370     EmitMem(mem);
1371     Emit("\n");
1372 }
1373 
Setle(Reg reg)1374 void AsmAssembler::Setle(Reg reg)
1375 {
1376     Emit("\tsetle\t");
1377     EmitReg(reg);
1378     Emit("\n");
1379 }
1380 
Setle(const Mem & mem)1381 void AsmAssembler::Setle(const Mem &mem)
1382 {
1383     Emit("\tsetle\t");
1384     EmitMem(mem);
1385     Emit("\n");
1386 }
1387 
Setae(Reg reg)1388 void AsmAssembler::Setae(Reg reg)
1389 {
1390     Emit("\tsetae\t");
1391     EmitReg(reg);
1392     Emit("\n");
1393 }
1394 
Setae(const Mem & mem)1395 void AsmAssembler::Setae(const Mem &mem)
1396 {
1397     Emit("\tsetae\t");
1398     EmitMem(mem);
1399     Emit("\n");
1400 }
1401 
Setge(Reg reg)1402 void AsmAssembler::Setge(Reg reg)
1403 {
1404     Emit("\tsetge\t");
1405     EmitReg(reg);
1406     Emit("\n");
1407 }
1408 
Setge(const Mem & mem)1409 void AsmAssembler::Setge(const Mem &mem)
1410 {
1411     Emit("\tsetge\t");
1412     EmitMem(mem);
1413     Emit("\n");
1414 }
1415 
Setne(Reg reg)1416 void AsmAssembler::Setne(Reg reg)
1417 {
1418     Emit("\tsetne\t");
1419     EmitReg(reg);
1420     Emit("\n");
1421 }
1422 
Setne(const Mem & mem)1423 void AsmAssembler::Setne(const Mem &mem)
1424 {
1425     Emit("\tsetne\t");
1426     EmitMem(mem);
1427     Emit("\n");
1428 }
1429 
Setb(Reg reg)1430 void AsmAssembler::Setb(Reg reg)
1431 {
1432     Emit("\tsetb\t");
1433     EmitReg(reg);
1434     Emit("\n");
1435 }
1436 
Setb(const Mem & mem)1437 void AsmAssembler::Setb(const Mem &mem)
1438 {
1439     Emit("\tsetb\t");
1440     EmitMem(mem);
1441     Emit("\n");
1442 }
1443 
Setl(Reg reg)1444 void AsmAssembler::Setl(Reg reg)
1445 {
1446     Emit("\tsetl\t");
1447     EmitReg(reg);
1448     Emit("\n");
1449 }
1450 
Setl(const Mem & mem)1451 void AsmAssembler::Setl(const Mem &mem)
1452 {
1453     Emit("\tsetl\t");
1454     EmitMem(mem);
1455     Emit("\n");
1456 }
1457 
Seta(Reg reg)1458 void AsmAssembler::Seta(Reg reg)
1459 {
1460     Emit("\tseta\t");
1461     EmitReg(reg);
1462     Emit("\n");
1463 }
1464 
Seta(const Mem & mem)1465 void AsmAssembler::Seta(const Mem &mem)
1466 {
1467     Emit("\tseta\t");
1468     EmitMem(mem);
1469     Emit("\n");
1470 }
1471 
Setg(Reg reg)1472 void AsmAssembler::Setg(Reg reg)
1473 {
1474     Emit("\tsetg\t");
1475     EmitReg(reg);
1476     Emit("\n");
1477 }
1478 
Setg(const Mem & mem)1479 void AsmAssembler::Setg(const Mem &mem)
1480 {
1481     Emit("\tsetg\t");
1482     EmitMem(mem);
1483     Emit("\n");
1484 }
1485 
Sete(Reg reg)1486 void AsmAssembler::Sete(Reg reg)
1487 {
1488     Emit("\tsete\t");
1489     EmitReg(reg);
1490     Emit("\n");
1491 }
1492 
Sete(const Mem & mem)1493 void AsmAssembler::Sete(const Mem &mem)
1494 {
1495     Emit("\tsete\t");
1496     EmitMem(mem);
1497     Emit("\n");
1498 }
1499 
Seto(Reg reg)1500 void AsmAssembler::Seto(Reg reg)
1501 {
1502     Emit("\tseto\t");
1503     EmitReg(reg);
1504     Emit("\n");
1505 }
1506 
Seto(const Mem & mem)1507 void AsmAssembler::Seto(const Mem &mem)
1508 {
1509     Emit("\tseto\t");
1510     EmitMem(mem);
1511     Emit("\n");
1512 }
1513 
1514 /* cmov */
Cmova(InsnSize insnSize,Reg srcReg,Reg destReg)1515 void AsmAssembler::Cmova(InsnSize insnSize, Reg srcReg, Reg destReg)
1516 {
1517     Emit("\tcmova");
1518     EmitInsnSuffix(insnSize);
1519     Emit("\t");
1520     EmitRegReg(srcReg, destReg);
1521     Emit("\n");
1522 }
1523 
Cmova(InsnSize insnSize,const Mem & mem,Reg reg)1524 void AsmAssembler::Cmova(InsnSize insnSize, const Mem &mem, Reg reg)
1525 {
1526     Emit("\tcmova");
1527     EmitInsnSuffix(insnSize);
1528     Emit("\t");
1529     EmitMemReg(mem, reg);
1530     Emit("\n");
1531 }
1532 
Cmovae(InsnSize insnSize,Reg srcReg,Reg destReg)1533 void AsmAssembler::Cmovae(InsnSize insnSize, Reg srcReg, Reg destReg)
1534 {
1535     Emit("\tcmovae");
1536     EmitInsnSuffix(insnSize);
1537     Emit("\t");
1538     EmitRegReg(srcReg, destReg);
1539     Emit("\n");
1540 }
1541 
Cmovae(InsnSize insnSize,const Mem & mem,Reg reg)1542 void AsmAssembler::Cmovae(InsnSize insnSize, const Mem &mem, Reg reg)
1543 {
1544     Emit("\tcmovae");
1545     EmitInsnSuffix(insnSize);
1546     Emit("\t");
1547     EmitMemReg(mem, reg);
1548     Emit("\n");
1549 }
1550 
Cmovb(InsnSize insnSize,Reg srcReg,Reg destReg)1551 void AsmAssembler::Cmovb(InsnSize insnSize, Reg srcReg, Reg destReg)
1552 {
1553     Emit("\tcmovb");
1554     EmitInsnSuffix(insnSize);
1555     Emit("\t");
1556     EmitRegReg(srcReg, destReg);
1557     Emit("\n");
1558 }
1559 
Cmovb(InsnSize insnSize,const Mem & mem,Reg reg)1560 void AsmAssembler::Cmovb(InsnSize insnSize, const Mem &mem, Reg reg)
1561 {
1562     Emit("\tcmovb");
1563     EmitInsnSuffix(insnSize);
1564     Emit("\t");
1565     EmitMemReg(mem, reg);
1566     Emit("\n");
1567 }
1568 
Cmovbe(InsnSize insnSize,Reg srcReg,Reg destReg)1569 void AsmAssembler::Cmovbe(InsnSize insnSize, Reg srcReg, Reg destReg)
1570 {
1571     Emit("\tcmovbe");
1572     EmitInsnSuffix(insnSize);
1573     Emit("\t");
1574     EmitRegReg(srcReg, destReg);
1575     Emit("\n");
1576 }
1577 
Cmovbe(InsnSize insnSize,const Mem & mem,Reg reg)1578 void AsmAssembler::Cmovbe(InsnSize insnSize, const Mem &mem, Reg reg)
1579 {
1580     Emit("\tcmovbe");
1581     EmitInsnSuffix(insnSize);
1582     Emit("\t");
1583     EmitMemReg(mem, reg);
1584     Emit("\n");
1585 }
Cmove(InsnSize insnSize,Reg srcReg,Reg destReg)1586 void AsmAssembler::Cmove(InsnSize insnSize, Reg srcReg, Reg destReg)
1587 {
1588     Emit("\tcmove");
1589     EmitInsnSuffix(insnSize);
1590     Emit("\t");
1591     EmitRegReg(srcReg, destReg);
1592     Emit("\n");
1593 }
1594 
Cmove(InsnSize insnSize,const Mem & mem,Reg reg)1595 void AsmAssembler::Cmove(InsnSize insnSize, const Mem &mem, Reg reg)
1596 {
1597     Emit("\tcmove");
1598     EmitInsnSuffix(insnSize);
1599     Emit("\t");
1600     EmitMemReg(mem, reg);
1601     Emit("\n");
1602 }
1603 
Cmovg(InsnSize insnSize,Reg srcReg,Reg destReg)1604 void AsmAssembler::Cmovg(InsnSize insnSize, Reg srcReg, Reg destReg)
1605 {
1606     Emit("\tcmovg");
1607     EmitInsnSuffix(insnSize);
1608     Emit("\t");
1609     EmitRegReg(srcReg, destReg);
1610     Emit("\n");
1611 }
1612 
Cmovg(InsnSize insnSize,const Mem & mem,Reg reg)1613 void AsmAssembler::Cmovg(InsnSize insnSize, const Mem &mem, Reg reg)
1614 {
1615     Emit("\tcmovg");
1616     EmitInsnSuffix(insnSize);
1617     Emit("\t");
1618     EmitMemReg(mem, reg);
1619     Emit("\n");
1620 }
1621 
Cmovge(InsnSize insnSize,Reg srcReg,Reg destReg)1622 void AsmAssembler::Cmovge(InsnSize insnSize, Reg srcReg, Reg destReg)
1623 {
1624     Emit("\tcmovge");
1625     EmitInsnSuffix(insnSize);
1626     Emit("\t");
1627     EmitRegReg(srcReg, destReg);
1628     Emit("\n");
1629 }
1630 
Cmovge(InsnSize insnSize,const Mem & mem,Reg reg)1631 void AsmAssembler::Cmovge(InsnSize insnSize, const Mem &mem, Reg reg)
1632 {
1633     Emit("\tcmovge");
1634     EmitInsnSuffix(insnSize);
1635     Emit("\t");
1636     EmitMemReg(mem, reg);
1637     Emit("\n");
1638 }
1639 
Cmovl(InsnSize insnSize,Reg srcReg,Reg destReg)1640 void AsmAssembler::Cmovl(InsnSize insnSize, Reg srcReg, Reg destReg)
1641 {
1642     Emit("\tcmovl");
1643     EmitInsnSuffix(insnSize);
1644     Emit("\t");
1645     EmitRegReg(srcReg, destReg);
1646     Emit("\n");
1647 }
1648 
Cmovl(InsnSize insnSize,const Mem & mem,Reg reg)1649 void AsmAssembler::Cmovl(InsnSize insnSize, const Mem &mem, Reg reg)
1650 {
1651     Emit("\tcmovl");
1652     EmitInsnSuffix(insnSize);
1653     Emit("\t");
1654     EmitMemReg(mem, reg);
1655     Emit("\n");
1656 }
1657 
Cmovle(InsnSize insnSize,Reg srcReg,Reg destReg)1658 void AsmAssembler::Cmovle(InsnSize insnSize, Reg srcReg, Reg destReg)
1659 {
1660     Emit("\tcmovle");
1661     EmitInsnSuffix(insnSize);
1662     Emit("\t");
1663     EmitRegReg(srcReg, destReg);
1664     Emit("\n");
1665 }
1666 
Cmovle(InsnSize insnSize,const Mem & mem,Reg reg)1667 void AsmAssembler::Cmovle(InsnSize insnSize, const Mem &mem, Reg reg)
1668 {
1669     Emit("\tcmovle");
1670     EmitInsnSuffix(insnSize);
1671     Emit("\t");
1672     EmitMemReg(mem, reg);
1673     Emit("\n");
1674 }
1675 
Cmovo(InsnSize insnSize,Reg srcReg,Reg destReg)1676 void AsmAssembler::Cmovo(InsnSize insnSize, Reg srcReg, Reg destReg)
1677 {
1678     Emit("\tcmovo");
1679     EmitInsnSuffix(insnSize);
1680     Emit("\t");
1681     EmitRegReg(srcReg, destReg);
1682     Emit("\n");
1683 }
1684 
Cmovne(InsnSize insnSize,const Mem & mem,Reg reg)1685 void AsmAssembler::Cmovne(InsnSize insnSize, const Mem &mem, Reg reg)
1686 {
1687     Emit("\tcmovne");
1688     EmitInsnSuffix(insnSize);
1689     Emit("\t");
1690     EmitMemReg(mem, reg);
1691     Emit("\n");
1692 }
1693 
Cmovne(InsnSize insnSize,Reg srcReg,Reg destReg)1694 void AsmAssembler::Cmovne(InsnSize insnSize, Reg srcReg, Reg destReg)
1695 {
1696     Emit("\tcmovne");
1697     EmitInsnSuffix(insnSize);
1698     Emit("\t");
1699     EmitRegReg(srcReg, destReg);
1700     Emit("\n");
1701 }
1702 
1703 /* call */
Call(InsnSize insnSize,Reg reg)1704 void AsmAssembler::Call(InsnSize insnSize, Reg reg)
1705 {
1706     Emit("\tcall");
1707     EmitInsnSuffix(insnSize);
1708     Emit("\t*");
1709     EmitReg(reg);
1710     Emit("\n");
1711 }
1712 
Call(InsnSize insnSize,const Mem & mem)1713 void AsmAssembler::Call(InsnSize insnSize, const Mem &mem)
1714 {
1715     Emit("\tcall");
1716     EmitInsnSuffix(insnSize);
1717     Emit("\t*");
1718     EmitMem(mem);
1719     Emit("\n");
1720 }
1721 
Call(InsnSize insnSize,int64 symIdx)1722 void AsmAssembler::Call(InsnSize insnSize, int64 symIdx)
1723 {
1724     Emit("\tcall");
1725     EmitInsnSuffix(insnSize);
1726     Emit("\t");
1727     EmitLabel(symIdx);
1728     Emit("\n");
1729 }
1730 
1731 /* ret */
Ret()1732 void AsmAssembler::Ret()
1733 {
1734     Emit("\tret\n");
1735 }
1736 
1737 /* leave */
Leave()1738 void AsmAssembler::Leave()
1739 {
1740     Emit("\tleave\n");
1741 }
1742 
1743 /* imul */
Imul(InsnSize insnSize,Reg srcReg,Reg destReg)1744 void AsmAssembler::Imul(InsnSize insnSize, Reg srcReg, Reg destReg)
1745 {
1746     Emit("\timul");
1747     EmitInsnSuffix(insnSize);
1748     Emit("\t");
1749     EmitRegReg(srcReg, destReg);
1750     Emit("\n");
1751 }
1752 
1753 /* mul float */
Mul(Reg srcReg,Reg destReg,bool isSingle)1754 void AsmAssembler::Mul(Reg srcReg, Reg destReg, bool isSingle)
1755 {
1756     if (isSingle) {
1757         Emit("\tmulss\t");
1758     } else {
1759         Emit("\tmulsd\t");
1760     }
1761     EmitRegReg(srcReg, destReg);
1762     Emit("\n");
1763 }
1764 
Mul(const Mem & mem,Reg reg,bool isSingle)1765 void AsmAssembler::Mul(const Mem &mem, Reg reg, bool isSingle)
1766 {
1767     if (isSingle) {
1768         Emit("\tmulss\t");
1769     } else {
1770         Emit("\tmulsd\t");
1771     }
1772     EmitMemReg(mem, reg);
1773     Emit("\n");
1774 }
1775 
1776 /* nop */
Nop(InsnSize insnSize,const Mem & mem)1777 void AsmAssembler::Nop(InsnSize insnSize, const Mem &mem)
1778 {
1779     Emit("\tnop");
1780     EmitInsnSuffix(insnSize);
1781     Emit("\t");
1782     EmitMem(mem);
1783     Emit("\n");
1784 }
1785 
Nop()1786 void AsmAssembler::Nop()
1787 {
1788     Emit("\tnop\n");
1789 }
1790 
1791 /* byte swap */
Bswap(InsnSize insnSize,Reg reg)1792 void AsmAssembler::Bswap(InsnSize insnSize, Reg reg)
1793 {
1794     Emit("\tbswap");
1795     EmitInsnSuffix(insnSize);
1796     Emit("\t");
1797     EmitReg(reg);
1798     Emit("\n");
1799 }
1800 
Xchg(InsnSize insnSize,Reg srcReg,Reg destReg)1801 void AsmAssembler::Xchg(InsnSize insnSize, Reg srcReg, Reg destReg)
1802 {
1803     Emit("\txchg");
1804     EmitInsnSuffix(insnSize);
1805     Emit("\t");
1806     EmitRegReg(srcReg, destReg);
1807     Emit("\n");
1808 }
1809 
1810 /* pseudo insn */
DealWithPseudoInst(const std::string & insn)1811 void AsmAssembler::DealWithPseudoInst(const std::string &insn)
1812 {
1813     Emit("\t");
1814     Emit(insn);
1815     Emit("\n");
1816 }
1817 
1818 /* floating point */
MovF(Reg srcReg,Reg destReg,bool isSingle)1819 void AsmAssembler::MovF(Reg srcReg, Reg destReg, bool isSingle)
1820 {
1821     if (isSingle) {
1822         Emit("\tmovss\t");
1823     } else {
1824         Emit("\tmovsd\t");
1825     }
1826     EmitRegReg(srcReg, destReg);
1827     Emit("\n");
1828 }
1829 
1830 /* floating point and */
And(Reg srcReg,Reg destReg,bool isSingle)1831 void AsmAssembler::And(Reg srcReg, Reg destReg, bool isSingle)
1832 {
1833     if (isSingle) {
1834         Emit("\tandps\t");
1835     } else {
1836         Emit("\tandpd\t");
1837     }
1838     EmitRegReg(srcReg, destReg);
1839     Emit("\n");
1840 }
1841 
And(const Mem & mem,Reg reg,bool isSingle)1842 void AsmAssembler::And(const Mem &mem, Reg reg, bool isSingle)
1843 {
1844     if (isSingle) {
1845         Emit("\tandps\t");
1846     } else {
1847         Emit("\tandpd\t");
1848     }
1849     EmitMemReg(mem, reg);
1850     Emit("\n");
1851 }
1852 
1853 /* floating div */
Divsd(Reg srcReg,Reg destReg)1854 void AsmAssembler::Divsd(Reg srcReg, Reg destReg)
1855 {
1856     Emit("\tdivsd\t");
1857     EmitRegReg(srcReg, destReg);
1858     Emit("\n");
1859 }
1860 
Divsd(const Mem & mem,Reg reg)1861 void AsmAssembler::Divsd(const Mem &mem, Reg reg)
1862 {
1863     Emit("\tdivsd\t");
1864     EmitMemReg(mem, reg);
1865     Emit("\n");
1866 }
1867 
1868 /* convert int2float */
Cvtsi2ss(InsnSize insnSize,Reg srcReg,Reg destReg)1869 void AsmAssembler::Cvtsi2ss(InsnSize insnSize, Reg srcReg, Reg destReg)
1870 {
1871     Emit("\tcvtsi2ss");
1872     EmitInsnSuffix(insnSize);
1873     Emit("\t");
1874     EmitRegReg(srcReg, destReg);
1875     Emit("\n");
1876 }
1877 
Cvtsi2sd(InsnSize insnSize,Reg srcReg,Reg destReg)1878 void AsmAssembler::Cvtsi2sd(InsnSize insnSize, Reg srcReg, Reg destReg)
1879 {
1880     Emit("\tcvtsi2sd");
1881     EmitInsnSuffix(insnSize);
1882     Emit("\t");
1883     EmitRegReg(srcReg, destReg);
1884     Emit("\n");
1885 }
1886 
1887 /*convert float2int */
Cvttsd2si(InsnSize insnSize,Reg srcReg,Reg destReg)1888 void AsmAssembler::Cvttsd2si(InsnSize insnSize, Reg srcReg, Reg destReg)
1889 {
1890     Emit("\tcvttsd2si");
1891     EmitInsnSuffix(insnSize);
1892     Emit("\t");
1893     EmitRegReg(srcReg, destReg);
1894     Emit("\n");
1895 }
1896 
Cvttss2si(InsnSize insnSize,Reg srcReg,Reg destReg)1897 void AsmAssembler::Cvttss2si(InsnSize insnSize, Reg srcReg, Reg destReg)
1898 {
1899     Emit("\tcvtss2si");
1900     EmitInsnSuffix(insnSize);
1901     Emit("\t");
1902     EmitRegReg(srcReg, destReg);
1903     Emit("\n");
1904 }
1905 
1906 /* convert float2float */
Cvtss2sd(Reg srcReg,Reg destReg)1907 void AsmAssembler::Cvtss2sd(Reg srcReg, Reg destReg)
1908 {
1909     Emit("\tcvtss2sd\t");
1910     EmitRegReg(srcReg, destReg);
1911     Emit("\n");
1912 }
1913 
Cvtsd2ss(Reg srcReg,Reg destReg)1914 void AsmAssembler::Cvtsd2ss(Reg srcReg, Reg destReg)
1915 {
1916     Emit("\tcvtsd2ss\t");
1917     EmitRegReg(srcReg, destReg);
1918     Emit("\n");
1919 }
1920 
1921 /* unordered compare */
Ucomisd(Reg srcReg,Reg destReg)1922 void AsmAssembler::Ucomisd(Reg srcReg, Reg destReg)
1923 {
1924     Emit("\tucomisd\t");
1925     EmitRegReg(srcReg, destReg);
1926     Emit("\n");
1927 }
1928 
Ucomiss(Reg srcReg,Reg destReg)1929 void AsmAssembler::Ucomiss(Reg srcReg, Reg destReg)
1930 {
1931     Emit("\tucomiss\t");
1932     EmitRegReg(srcReg, destReg);
1933     Emit("\n");
1934 }
1935 
Cmpeqsd(Reg srcReg,Reg destReg)1936 void AsmAssembler::Cmpeqsd(Reg srcReg, Reg destReg)
1937 {
1938     Emit("\tcmpeqsd\t");
1939     EmitRegReg(srcReg, destReg);
1940     Emit("\n");
1941 }
1942 
1943 /* float sqrt*/
Sqrtss_r(Reg srcReg,Reg destReg)1944 void AsmAssembler::Sqrtss_r(Reg srcReg, Reg destReg)
1945 {
1946     Emit("\tsqrtss\t");
1947     EmitRegReg(srcReg, destReg);
1948     Emit("\n");
1949 }
1950 
Sqrtsd_r(Reg srcReg,Reg destReg)1951 void AsmAssembler::Sqrtsd_r(Reg srcReg, Reg destReg)
1952 {
1953     Emit("\tsqrtsd\t");
1954     EmitRegReg(srcReg, destReg);
1955     Emit("\n");
1956 }
1957 /* end of X64 instructions */
1958 } /* namespace assembler */
1959