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