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