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