001 /*
002 * This file is part of the Jikes RVM project (http://jikesrvm.org).
003 *
004 * This file is licensed to You under the Eclipse Public License (EPL);
005 * You may not use this file except in compliance with the License. You
006 * may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/eclipse-1.0.php
009 *
010 * See the COPYRIGHT.txt file distributed with this work for information
011 * regarding copyright ownership.
012 */
013 package org.jikesrvm.compilers.opt.mir2mc.ia32;
014
015 import java.util.ArrayList;
016 import static org.jikesrvm.ia32.ArchConstants.SSE2_FULL;
017 import org.jikesrvm.ArchitectureSpecificOpt.AssemblerOpt;
018 import org.jikesrvm.ArchitectureSpecific.Assembler;
019 import org.jikesrvm.VM;
020 import org.jikesrvm.Constants;
021 import org.jikesrvm.compilers.common.assembler.ForwardReference;
022 import org.jikesrvm.compilers.opt.OptimizingCompilerException;
023 import org.jikesrvm.compilers.opt.ir.MIR_BinaryAcc;
024 import org.jikesrvm.compilers.opt.ir.MIR_Branch;
025 import org.jikesrvm.compilers.opt.ir.MIR_Call;
026 import org.jikesrvm.compilers.opt.ir.MIR_Compare;
027 import org.jikesrvm.compilers.opt.ir.MIR_CondBranch;
028 import org.jikesrvm.compilers.opt.ir.MIR_Lea;
029 import org.jikesrvm.compilers.opt.ir.MIR_LowTableSwitch;
030 import org.jikesrvm.compilers.opt.ir.MIR_Move;
031 import org.jikesrvm.compilers.opt.ir.MIR_Test;
032 import org.jikesrvm.compilers.opt.ir.MIR_Unary;
033 import org.jikesrvm.compilers.opt.ir.MIR_UnaryNoRes;
034 import org.jikesrvm.compilers.opt.ir.IR;
035 import org.jikesrvm.compilers.opt.ir.Instruction;
036 import org.jikesrvm.compilers.opt.ir.OperandEnumeration;
037 import org.jikesrvm.compilers.opt.ir.Operator;
038 import org.jikesrvm.compilers.opt.ir.Operators;
039 import org.jikesrvm.compilers.opt.ir.Register;
040 import org.jikesrvm.compilers.opt.ir.ia32.PhysicalRegisterSet;
041 import org.jikesrvm.compilers.opt.ir.operand.BranchOperand;
042 import org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand;
043 import org.jikesrvm.compilers.opt.ir.operand.MemoryOperand;
044 import org.jikesrvm.compilers.opt.ir.operand.Operand;
045 import org.jikesrvm.compilers.opt.ir.operand.RegisterOperand;
046 import org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand;
047 import org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand;
048 import org.jikesrvm.compilers.opt.regalloc.ia32.PhysicalRegisterConstants;
049 import org.jikesrvm.ia32.TrapConstants;
050 import org.vmmagic.pragma.NoInline;
051 import org.vmmagic.unboxed.Offset;
052
053 /**
054 * This class provides support functionality used by the generated
055 * Assembler; it handles basic impedance-matching functionality
056 * such as determining which addressing mode is suitable for a given
057 * IA32MemoryOperand. This class also provides some boilerplate
058 * methods that do not depend on how instructions sould actually be
059 * assembled, like the top-level generateCode driver. This class is
060 * not meant to be used in isolation, but rather to provide support
061 * from the Assembler.
062 */
063 abstract class AssemblerBase extends Assembler
064 implements Operators, Constants, PhysicalRegisterConstants {
065
066 private static final boolean DEBUG_ESTIMATE = false;
067
068 /**
069 * Hold EBP register object for use in estimating size of memory operands.
070 */
071 private final Register EBP;
072
073 /**
074 * Hold EBP register object for use in estimating size of memory operands.
075 */
076 private final Register ESP;
077
078 /**
079 * Operators with byte arguments
080 */
081 private static final Operator[] byteSizeOperators;
082
083 /**
084 * Operators with word arguments
085 */
086 private static final Operator[] wordSizeOperators;
087
088 /**
089 * Operators with quad arguments
090 */
091 private static final Operator[] quadSizeOperators;
092
093 static {
094 ArrayList<Operator> temp = new ArrayList<Operator>();
095 for (Operator opr : Operator.OperatorArray) {
096 if (opr != null && opr.toString().indexOf("__b") != -1) {
097 temp.add(opr);
098 }
099 }
100 byteSizeOperators = temp.toArray(new Operator[temp.size()]);
101 temp.clear();
102 for (Operator opr : Operator.OperatorArray) {
103 if (opr != null && opr.toString().indexOf("__w") != -1) {
104 temp.add(opr);
105 }
106 }
107 wordSizeOperators = temp.toArray(new Operator[temp.size()]);
108 for (Operator opr : Operator.OperatorArray) {
109 if (opr != null && opr.toString().indexOf("__q") != -1) {
110 temp.add(opr);
111 }
112 }
113 quadSizeOperators = temp.toArray(new Operator[temp.size()]);
114 }
115
116 /**
117 * Construct Assembler object
118 * @see Assembler
119 */
120 AssemblerBase(int bytecodeSize, boolean shouldPrint, IR ir) {
121 super(bytecodeSize, shouldPrint);
122 EBP = ir.regpool.getPhysicalRegisterSet().getEBP();
123 ESP = ir.regpool.getPhysicalRegisterSet().getESP();
124 }
125
126 /**
127 * Should code created by this assembler instance be allocated in the
128 * hot code code space? The default answer for opt compiled code is yes
129 * (otherwise why are we opt compiling it?).
130 */
131 protected boolean isHotCode() { return true; }
132
133 /**
134 * Is the given operand an immediate? In the IA32 assembly, one
135 * cannot specify floating-point constants, so the possible
136 * immediates we may see are IntegerConstants and
137 * TrapConstants (a trap constant really is an integer), and
138 * jump targets for which the exact offset is known.
139 *
140 * @see #getImm
141 *
142 * @param op the operand being queried
143 * @return true if op represents an immediate
144 */
145 boolean isImm(Operand op) {
146 return (op instanceof IntConstantOperand) ||
147 (op instanceof TrapCodeOperand) ||
148 (op instanceof BranchOperand && op.asBranch().target.getmcOffset() >= 0);
149 }
150
151 /**
152 * Return the IA32 ISA encoding of the immediate value
153 * represented by the the given operand. This method assumes the
154 * operand is an immediate and will likely throw a
155 * ClassCastException if this not the case. It treats
156 * BranchOperands somewhat differently than isImm does: in
157 * case a branch target is not resolved, it simply returns a wrong
158 * answer and trusts the caller to ignore it. This behavior
159 * simplifies life when generating code for ImmOrLabel operands.
160 *
161 * @see #isImm
162 *
163 * @param op the operand being queried
164 * @return the immediate value represented by the operand
165 */
166 int getImm(Operand op) {
167 if (op.isIntConstant()) {
168 return op.asIntConstant().value;
169 } else if (op.isBranch()) {
170 // used by ImmOrLabel stuff
171 return op.asBranch().target.getmcOffset();
172 } else {
173 return ((TrapCodeOperand) op).getTrapCode() + TrapConstants.RVM_TRAP_BASE;
174 }
175 }
176
177 /**
178 * Is the given operand a register operand?
179 *
180 * @see #getReg
181 *
182 * @param op the operand being queried
183 * @return true if op is an RegisterOperand
184 */
185 boolean isReg(Operand op) {
186 return op.isRegister();
187 }
188
189 boolean isGPR_Reg(Operand op) {
190 return isReg(op);
191 }
192
193 boolean isFPR_Reg(Operand op) {
194 return isReg(op);
195 }
196
197 boolean isMM_Reg(Operand op) {
198 return false; // MM registers not currently supported in the OPT compiler
199 }
200
201 boolean isXMM_Reg(Operand op) {
202 return op.isRegister() && (op.isFloat() || op.isDouble());
203 }
204
205 /**
206 * Return the machine-level register number corresponding to a given integer
207 * Register. The optimizing compiler has its own notion of register
208 * numbers, which is not the same as the numbers used by the IA32 ISA. This
209 * method takes an optimizing compiler register and translates it into the
210 * appropriate machine-level encoding. This method is not applied directly to
211 * operands, but rather to register objects.
212 *
213 * @see #getBase
214 * @see #getIndex
215 *
216 * @param reg the register being queried
217 * @return the 3 bit machine-level encoding of reg
218 */
219 private GPR getGPMachineRegister(Register reg) {
220 if (VM.VerifyAssertions) {
221 VM._assert(PhysicalRegisterSet.getPhysicalRegisterType(reg) == INT_REG);
222 }
223 return GPR.lookup(reg.number - FIRST_INT);
224 }
225
226 /**
227 * Return the machine-level register number corresponding to a
228 * given Register. The optimizing compiler has its own notion
229 * of register numbers, which is not the same as the numbers used
230 * by the IA32 ISA. This method takes an optimizing compiler
231 * register and translates it into the appropriate machine-level
232 * encoding. This method is not applied directly to operands, but
233 * rather to register objects.
234 *
235 * @see #getReg
236 * @see #getBase
237 * @see #getIndex
238 *
239 * @param reg the register being queried
240 * @return the 3 bit machine-level encoding of reg
241 */
242 private MachineRegister getMachineRegister(Register reg) {
243 int type = PhysicalRegisterSet.getPhysicalRegisterType(reg);
244 MachineRegister result;
245 if (type == INT_REG) {
246 result = GPR.lookup(reg.number - FIRST_INT);
247 } else {
248 if (VM.VerifyAssertions) VM._assert(type == DOUBLE_REG);
249 if (SSE2_FULL) {
250 if (reg.number < FIRST_SPECIAL) {
251 result = XMM.lookup(reg.number - FIRST_DOUBLE);
252 } else if (reg.number == ST0) {
253 result = FP0;
254 } else {
255 if (VM.VerifyAssertions) VM._assert(reg.number == ST1);
256 result = FP1;
257 }
258 } else {
259 result = FPR.lookup(reg.number - FIRST_DOUBLE);
260 }
261 }
262 return result;
263 }
264
265 /**
266 * Given a register operand, return the 3 bit IA32 ISA encoding
267 * of that register. This function translates an optimizing
268 * compiler register operand into the 3 bit IA32 ISA encoding that
269 * can be passed to the Assembler. This function assumes its
270 * operand is a register operand, and will blow up if it is not;
271 * use isReg to check operands passed to this method.
272 *
273 * @see #isReg
274 *
275 * @param op the register operand being queried
276 * @return the 3 bit IA32 ISA encoding of op
277 */
278 MachineRegister getReg(Operand op) {
279 return getMachineRegister(op.asRegister().getRegister());
280 }
281
282 GPR getGPR_Reg(Operand op) {
283 return getGPMachineRegister(op.asRegister().getRegister());
284 }
285
286 FPR getFPR_Reg(Operand op) {
287 return (FPR)getMachineRegister(op.asRegister().getRegister());
288 }
289
290 MM getMM_Reg(Operand op) {
291 VM._assert(false, "MM registers not currently supported in the opt compiler");
292 return null;
293 }
294
295 XMM getXMM_Reg(Operand op) {
296 return (XMM)getMachineRegister(op.asRegister().getRegister());
297 }
298
299 /**
300 * Given a memory operand, return the 3 bit IA32 ISA encoding
301 * of its base regsiter. This function translates the optimizing
302 * compiler register operand representing the base of the given
303 * memory operand into the 3 bit IA32 ISA encoding that
304 * can be passed to the Assembler. This function assumes its
305 * operand is a memory operand, and will blow up if it is not;
306 * one should confirm an operand really has a base register before
307 * invoking this method on it.
308 *
309 * @see #isRegDisp
310 * @see #isRegIdx
311 * @see #isRegInd
312 *
313 * @param op the register operand being queried
314 * @return the 3 bit IA32 ISA encoding of the base register of op
315 */
316 GPR getBase(Operand op) {
317 return getGPMachineRegister(((MemoryOperand) op).base.getRegister());
318 }
319
320 /**
321 * Given a memory operand, return the 3 bit IA32 ISA encoding
322 * of its index regsiter. This function translates the optimizing
323 * compiler register operand representing the index of the given
324 * memory operand into the 3 bit IA32 ISA encoding that
325 * can be passed to the Assembler. This function assumes its
326 * operand is a memory operand, and will blow up if it is not;
327 * one should confirm an operand really has an index register before
328 * invoking this method on it.
329 *
330 * @see #isRegIdx
331 * @see #isRegOff
332 *
333 * @param op the register operand being queried
334 * @return the 3 bit IA32 ISA encoding of the index register of op
335 */
336 GPR getIndex(Operand op) {
337 return getGPMachineRegister(((MemoryOperand) op).index.getRegister());
338 }
339
340 /**
341 * Given a memory operand, return the 2 bit IA32 ISA encoding
342 * of its scale, suitable for passing to the Assembler to mask
343 * into a SIB byte. This function assumes its operand is a memory
344 * operand, and will blow up if it is not; one should confirm an
345 * operand really has a scale before invoking this method on it.
346 *
347 * @see #isRegIdx
348 * @see #isRegOff
349 *
350 * @param op the register operand being queried
351 * @return the IA32 ISA encoding of the scale of op
352 */
353 short getScale(Operand op) {
354 return ((MemoryOperand) op).scale;
355 }
356
357 /**
358 * Given a memory operand, return the 2 bit IA32 ISA encoding
359 * of its scale, suitable for passing to the Assembler to mask
360 * into a SIB byte. This function assumes its operand is a memory
361 * operand, and will blow up if it is not; one should confirm an
362 * operand really has a scale before invoking this method on it.
363 *
364 * @see #isRegIdx
365 * @see #isRegOff
366 *
367 * @param op the register operand being queried
368 * @return the IA32 ISA encoding of the scale of op
369 */
370 Offset getDisp(Operand op) {
371 return ((MemoryOperand) op).disp;
372 }
373
374 /**
375 * Determine if a given operand is a memory operand representing
376 * register-displacement mode addressing. This method takes an
377 * arbitrary operand, checks whether it is a memory operand, and,
378 * if it is, checks whether it should be assembled as IA32
379 * register-displacement mode. That is, does it have a non-zero
380 * displacement and a base register, but no scale and no index
381 * register?
382 *
383 * @param op the operand being queried
384 * @return true if op should be assembled as register-displacement mode
385 */
386 boolean isRegDisp(Operand op) {
387 if (op instanceof MemoryOperand) {
388 MemoryOperand mop = (MemoryOperand) op;
389 return (mop.base != null) && (mop.index == null) && (!mop.disp.isZero()) && (mop.scale == 0);
390 } else {
391 return false;
392 }
393 }
394
395 /**
396 * Determine if a given operand is a memory operand representing
397 * absolute mode addressing. This method takes an
398 * arbitrary operand, checks whether it is a memory operand, and,
399 * if it is, checks whether it should be assembled as IA32
400 * absolute address mode. That is, does it have a non-zero
401 * displacement, but no scale, no scale and no index register?
402 *
403 * @param op the operand being queried
404 * @return true if op should be assembled as absolute mode
405 */
406 boolean isAbs(Operand op) {
407 if (op instanceof MemoryOperand) {
408 MemoryOperand mop = (MemoryOperand) op;
409 return (mop.base == null) && (mop.index == null) && (!mop.disp.isZero()) && (mop.scale == 0);
410 } else {
411 return false;
412 }
413 }
414
415 /**
416 * Determine if a given operand is a memory operand representing
417 * register-indirect mode addressing. This method takes an
418 * arbitrary operand, checks whether it is a memory operand, and,
419 * if it is, checks whether it should be assembled as IA32
420 * register-displacement mode. That is, does it have a base
421 * register, but no displacement, no scale and no index
422 * register?
423 *
424 * @param op the operand being queried
425 * @return true if op should be assembled as register-indirect mode
426 */
427 boolean isRegInd(Operand op) {
428 if (op instanceof MemoryOperand) {
429 MemoryOperand mop = (MemoryOperand) op;
430 return (mop.base != null) && (mop.index == null) && (mop.disp.isZero()) && (mop.scale == 0);
431 } else {
432 return false;
433 }
434 }
435
436 /**
437 * Determine if a given operand is a memory operand representing
438 * register-offset mode addressing. This method takes an
439 * arbitrary operand, checks whether it is a memory operand, and,
440 * if it is, checks whether it should be assembled as IA32
441 * register-offset mode. That is, does it have a non-zero
442 * displacement, a scale parameter and an index register, but no
443 * base register?
444 *
445 * @param op the operand being queried
446 * @return true if op should be assembled as register-offset mode
447 */
448 boolean isRegOff(Operand op) {
449 if (op instanceof MemoryOperand) {
450 MemoryOperand mop = (MemoryOperand) op;
451 return (mop.base == null) && (mop.index != null);
452 } else {
453 return false;
454 }
455 }
456
457 /**
458 * Determine if a given operand is a memory operand representing
459 * the full glory of scaled-index-base addressing. This method takes an
460 * arbitrary operand, checks whether it is a memory operand, and,
461 * if it is, checks whether it should be assembled as IA32
462 * SIB mode. That is, does it have a non-zero
463 * displacement, a scale parameter, a base register and an index
464 * register?
465 *
466 * @param op the operand being queried
467 * @return true if op should be assembled as SIB mode
468 */
469 boolean isRegIdx(Operand op) {
470 if (op instanceof MemoryOperand) {
471 return !(isAbs(op) || isRegInd(op) || isRegDisp(op) || isRegOff(op));
472 } else {
473 return false;
474 }
475 }
476
477 /**
478 * Return the condition bits of a given optimizing compiler
479 * condition operand. This method returns the IA32 ISA bits
480 * representing a given condition operand, suitable for passing to
481 * the Assembler to encode into the opcode of a SET, Jcc or
482 * CMOV instruction. This being IA32, there are of course
483 * exceptions in the binary encoding of conditions (see FCMOV),
484 * but the Assembler handles that. This function assumes its
485 * argument is an IA32ConditionOperand, and will blow up if it
486 * is not.
487 *
488 * @param op the operand being queried
489 * @return the bits that (usually) represent the given condition
490 * in the IA32 ISA */
491 byte getCond(Operand op) {
492 return ((IA32ConditionOperand) op).value;
493 }
494
495 /**
496 * Is the given operand an IA32 condition operand?
497 *
498 * @param op the operand being queried
499 * @return true if op is an IA32 condition operand
500 */
501 boolean isCond(Operand op) {
502 return (op instanceof IA32ConditionOperand);
503 }
504
505 /**
506 * Return the label representing the target of the given branch
507 * operand. These labels are used to represent branch targets
508 * that have not yet been assembled, and so cannot be given
509 * concrete machine code offsets. All instructions are nunbered
510 * just prior to assembly, and these numbers are used as labels.
511 * This method also returns 0 (not a valid label) for int
512 * constants to simplify generation of branches (the branch
513 * generation code will ignore this invalid label; it is used to
514 * prevent type exceptions). This method assumes its operand is a
515 * branch operand (or an int) and will blow up if it is not.
516 *
517 * @param op the branch operand being queried
518 * @return the label representing the branch target
519 */
520 int getLabel(Operand op) {
521 if (op instanceof IntConstantOperand) {
522 // used by ImmOrLabel stuff
523 return 0;
524 } else {
525 if (op.asBranch().target.getmcOffset() < 0) {
526 return -op.asBranch().target.getmcOffset();
527 } else {
528 return -1;
529 }
530 }
531 }
532
533 /**
534 * Is the given operand a branch target that requires a label?
535 *
536 * @see #getLabel
537 *
538 * @param op the operand being queried
539 * @return true if it represents a branch requiring a label target
540 */
541 boolean isLabel(Operand op) {
542 return (op instanceof BranchOperand && op.asBranch().target.getmcOffset() < 0);
543 }
544
545 /**
546 * Is the given operand a branch target?
547 *
548 * @see #getLabel
549 * @see #isLabel
550 *
551 * @param op the operand being queried
552 * @return true if it represents a branch target
553 */
554 @NoInline
555 boolean isImmOrLabel(Operand op) {
556 // TODO: Remove NoInlinePragma, work around for leave SSA bug
557 return (isImm(op) || isLabel(op));
558 }
559
560 /**
561 * Does the given instruction operate upon byte-sized data? The
562 * opt compiler does not represent the size of register data, so
563 * this method typically looks at the memory operand, if any, and
564 * checks whether that is a byte. This does not work for the
565 * size-converting moves (MOVSX and MOVZX), and those instructions
566 * use the operator convention that __b on the end of the operator
567 * name means operate upon byte data.
568 *
569 * @param inst the instruction being queried
570 * @return true if inst operates upon byte data
571 */
572 boolean isByte(Instruction inst) {
573 for(Operator opr : byteSizeOperators){
574 if (opr == inst.operator) {
575 return true;
576 }
577 }
578
579 for (int i = 0; i < inst.getNumberOfOperands(); i++) {
580 Operand op = inst.getOperand(i);
581 if (op instanceof MemoryOperand) {
582 return (((MemoryOperand) op).size == 1);
583 }
584 }
585
586 return false;
587 }
588
589 /**
590 * Does the given instruction operate upon word-sized data? The
591 * opt compiler does not represent the size of register data, so
592 * this method typically looks at the memory operand, if any, and
593 * checks whether that is a word. This does not work for the
594 * size-converting moves (MOVSX and MOVZX), and those instructions
595 * use the operator convention that __w on the end of the operator
596 * name means operate upon word data.
597 *
598 * @param inst the instruction being queried
599 * @return true if inst operates upon word data
600 */
601 boolean isWord(Instruction inst) {
602 for(Operator opr : wordSizeOperators){
603 if (opr == inst.operator) {
604 return true;
605 }
606 }
607
608 for (int i = 0; i < inst.getNumberOfOperands(); i++) {
609 Operand op = inst.getOperand(i);
610 if (op instanceof MemoryOperand) {
611 return (((MemoryOperand) op).size == 2);
612 }
613 }
614
615 return false;
616 }
617
618 /**
619 * Does the given instruction operate upon quad-sized data? The
620 * opt compiler does not represent the size of register data, so
621 * this method typically looks at the memory operand, if any, and
622 * checks whether that is a byte. This method also recognizes
623 * the operator convention that __q on the end of the operator
624 * name means operate upon quad data; no operator currently uses
625 * this convention.
626 *
627 * @param inst the instruction being queried
628 * @return true if inst operates upon quad data
629 */
630 boolean isQuad(Instruction inst) {
631 for(Operator opr : quadSizeOperators){
632 if (opr == inst.operator) {
633 return true;
634 }
635 }
636
637 for (int i = 0; i < inst.getNumberOfOperands(); i++) {
638 Operand op = inst.getOperand(i);
639 if (op instanceof MemoryOperand) {
640 return (((MemoryOperand) op).size == 8);
641 }
642 }
643
644 return false;
645 }
646
647 /**
648 * Given a forward branch instruction and its target,
649 * determine (conservatively) if the relative offset to the
650 * target is less than 127 bytes
651 * @param start the branch instruction
652 * @param target the value of the mcOffset of the target label
653 * @return true if the relative offset will be less than 127, false otherwise
654 */
655 protected boolean targetIsClose(Instruction start, int target) {
656 Instruction inst = start.nextInstructionInCodeOrder();
657 final int budget = 120; // slight fudge factor could be 127
658 int offset = 0;
659 while (true) {
660 if (offset <= budget) return false;
661 if (inst.getmcOffset() == target) {
662 return true;
663 }
664 offset += estimateSize(inst, offset);
665 inst = inst.nextInstructionInCodeOrder();
666 }
667 }
668
669 protected int estimateSize(Instruction inst, int offset) {
670 switch (inst.getOpcode()) {
671 case LABEL_opcode:
672 return (4 - offset) & 3; // return size of nop required for alignment
673 case BBEND_opcode:
674 case READ_CEILING_opcode:
675 case WRITE_FLOOR_opcode:
676 case UNINT_BEGIN_opcode:
677 case UNINT_END_opcode: {
678 // these generate no code
679 return 0;
680 }
681 case IA32_METHODSTART_opcode:
682 return 12;
683 // Generated from the same case in Assembler
684 case IA32_ADC_opcode:
685 case IA32_ADD_opcode:
686 case IA32_AND_opcode:
687 case IA32_OR_opcode:
688 case IA32_SBB_opcode:
689 case IA32_XOR_opcode: {
690 int size = 2; // opcode + modr/m
691 size += operandCost(MIR_BinaryAcc.getResult(inst), true);
692 size += operandCost(MIR_BinaryAcc.getValue(inst), true);
693 return size;
694 }
695 case IA32_CMP_opcode: {
696 int size = 2; // opcode + modr/m
697 size += operandCost(MIR_Compare.getVal1(inst), true);
698 size += operandCost(MIR_Compare.getVal2(inst), true);
699 return size;
700 }
701 case IA32_TEST_opcode: {
702 int size = 2; // opcode + modr/m
703 size += operandCost(MIR_Test.getVal1(inst), false);
704 size += operandCost(MIR_Test.getVal2(inst), false);
705 return size;
706 }
707 case IA32_ADDSD_opcode:
708 case IA32_SUBSD_opcode:
709 case IA32_MULSD_opcode:
710 case IA32_DIVSD_opcode:
711 case IA32_XORPD_opcode:
712 case IA32_SQRTSD_opcode:
713 case IA32_ADDSS_opcode:
714 case IA32_SUBSS_opcode:
715 case IA32_MULSS_opcode:
716 case IA32_DIVSS_opcode:
717 case IA32_XORPS_opcode: {
718 int size = 4; // opcode + modr/m
719 Operand value = MIR_BinaryAcc.getValue(inst);
720 size += operandCost(value, false);
721 return size;
722 }
723 case IA32_UCOMISS_opcode: {
724 int size = 3; // opcode + modr/m
725 Operand val2 = MIR_Compare.getVal2(inst);
726 size += operandCost(val2, false);
727 return size;
728 }
729 case IA32_UCOMISD_opcode: {
730 int size = 4; // opcode + modr/m
731 Operand val2 = MIR_Compare.getVal2(inst);
732 size += operandCost(val2, false);
733 return size;
734 }
735 case IA32_CVTSI2SS_opcode:
736 case IA32_CVTSI2SD_opcode:
737 case IA32_CVTSS2SD_opcode:
738 case IA32_CVTSD2SS_opcode:
739 case IA32_CVTSD2SI_opcode:
740 case IA32_CVTTSD2SI_opcode:
741 case IA32_CVTSS2SI_opcode:
742 case IA32_CVTTSS2SI_opcode: {
743 int size = 4; // opcode + modr/m
744 Operand result = MIR_Unary.getResult(inst);
745 Operand value = MIR_Unary.getVal(inst);
746 size += operandCost(result, false);
747 size += operandCost(value, false);
748 return size;
749 }
750 case IA32_CMPEQSD_opcode:
751 case IA32_CMPLTSD_opcode:
752 case IA32_CMPLESD_opcode:
753 case IA32_CMPUNORDSD_opcode:
754 case IA32_CMPNESD_opcode:
755 case IA32_CMPNLTSD_opcode:
756 case IA32_CMPNLESD_opcode:
757 case IA32_CMPORDSD_opcode:
758 case IA32_CMPEQSS_opcode:
759 case IA32_CMPLTSS_opcode:
760 case IA32_CMPLESS_opcode:
761 case IA32_CMPUNORDSS_opcode:
762 case IA32_CMPNESS_opcode:
763 case IA32_CMPNLTSS_opcode:
764 case IA32_CMPNLESS_opcode:
765 case IA32_CMPORDSS_opcode: {
766 int size = 5; // opcode + modr/m + type
767 Operand value = MIR_BinaryAcc.getValue(inst);
768 size += operandCost(value, false);
769 return size;
770 }
771 case IA32_MOVD_opcode:
772 case IA32_MOVLPD_opcode:
773 case IA32_MOVQ_opcode:
774 case IA32_MOVSS_opcode:
775 case IA32_MOVSD_opcode: {
776 int size = 4; // opcode + modr/m
777 Operand result = MIR_Move.getResult(inst);
778 Operand value = MIR_Move.getValue(inst);
779 size += operandCost(result, false);
780 size += operandCost(value, false);
781 return size;
782 }
783 case IA32_PUSH_opcode: {
784 Operand op = MIR_UnaryNoRes.getVal(inst);
785 int size = 0;
786 if (op instanceof RegisterOperand) {
787 size += 1;
788 } else if (op instanceof IntConstantOperand) {
789 if (fits(((IntConstantOperand) op).value, 8)) {
790 size += 2;
791 } else {
792 size += 5;
793 }
794 } else {
795 size += (2 + operandCost(op, true));
796 }
797 return size;
798 }
799 case IA32_LEA_opcode: {
800 int size = 2; // opcode + 1 byte modr/m
801 size += operandCost(MIR_Lea.getResult(inst), false);
802 size += operandCost(MIR_Lea.getValue(inst), false);
803 return size;
804 }
805 case IA32_MOV_opcode: {
806 int size = 2; // opcode + modr/m
807 Operand result = MIR_Move.getResult(inst);
808 Operand value = MIR_Move.getValue(inst);
809 size += operandCost(result, false);
810 size += operandCost(value, false);
811 return size;
812 }
813 case MIR_LOWTABLESWITCH_opcode:
814 return MIR_LowTableSwitch.getNumberOfTargets(inst)*4 + 14;
815 case IA32_OFFSET_opcode:
816 return 4;
817 case IA32_JCC_opcode:
818 case IA32_JMP_opcode:
819 return 6; // assume long form
820 case IA32_LOCK_opcode:
821 return 1;
822 case IG_PATCH_POINT_opcode:
823 return 8;
824 case IA32_INT_opcode:
825 return 2;
826 case IA32_RET_opcode:
827 return 3;
828 case IA32_CALL_opcode:
829 Operand target = MIR_Call.getTarget(inst);
830 if (isImmOrLabel(target)) {
831 return 5; // opcode + 32bit immediate
832 } else {
833 return 2 + operandCost(target, false); // opcode + modr/m
834 }
835 default: {
836 int size = 3; // 2 bytes opcode + 1 byte modr/m
837 for (OperandEnumeration opEnum = inst.getRootOperands(); opEnum.hasMoreElements();) {
838 Operand op = opEnum.next();
839 size += operandCost(op, false);
840 }
841 return size;
842 }
843 }
844 }
845
846 private int operandCost(Operand op, boolean shortFormImmediate) {
847 if (op instanceof MemoryOperand) {
848 MemoryOperand mop = (MemoryOperand) op;
849 // If it's a 2byte mem location, we're going to need an override prefix
850 int prefix = mop.size == 2 ? 1 : 0;
851
852 // Deal with EBP wierdness
853 if (mop.base != null && mop.base.getRegister() == EBP) {
854 if (mop.index != null) {
855 // forced into SIB + 32 bit displacement no matter what disp is
856 return prefix + 5;
857 }
858 if (fits(mop.disp, 8)) {
859 return prefix + 1;
860 } else {
861 return prefix + 4;
862 }
863 }
864 if (mop.index != null && mop.index.getRegister() == EBP) {
865 // forced into SIB + 32 bit displacement no matter what disp is
866 return prefix + 5;
867 }
868
869 // Deal with ESP wierdness -- requires SIB byte even when index is null
870 if (mop.base != null && mop.base.getRegister() == ESP) {
871 if (fits(mop.disp, 8)) {
872 return prefix + 2;
873 } else {
874 return prefix + 5;
875 }
876 }
877
878 if (mop.index == null) {
879 // just displacement to worry about
880 if (mop.disp.isZero()) {
881 return prefix + 0;
882 } else if (fits(mop.disp, 8)) {
883 return prefix + 1;
884 } else {
885 return prefix + 4;
886 }
887 } else {
888 // have a SIB
889 if (mop.base == null && mop.scale != 0) {
890 // forced to 32 bit displacement even if it would fit in 8
891 return prefix + 5;
892 } else {
893 if (mop.disp.isZero()) {
894 return prefix + 1;
895 } else if (fits(mop.disp, 8)) {
896 return prefix + 2;
897 } else {
898 return prefix + 5;
899 }
900 }
901 }
902 } else if (op instanceof IntConstantOperand) {
903 if (shortFormImmediate && fits(((IntConstantOperand) op).value, 8)) {
904 return 1;
905 } else {
906 return 4;
907 }
908 } else {
909 return 0;
910 }
911 }
912
913 /**
914 * Emit the given instruction, assuming that
915 * it is a MIR_CondBranch instruction
916 * and has a JCC operator
917 *
918 * @param inst the instruction to assemble
919 */
920 protected void doJCC(Instruction inst) {
921 byte cond = getCond(MIR_CondBranch.getCond(inst));
922 if (isImm(MIR_CondBranch.getTarget(inst))) {
923 emitJCC_Cond_Imm(cond, getImm(MIR_CondBranch.getTarget(inst)));
924 } else {
925 if (VM.VerifyAssertions && !isLabel(MIR_CondBranch.getTarget(inst))) VM._assert(false, inst.toString());
926 int sourceLabel = -inst.getmcOffset();
927 int targetLabel = getLabel(MIR_CondBranch.getTarget(inst));
928 int delta = targetLabel - sourceLabel;
929 if (VM.VerifyAssertions) VM._assert(delta >= 0);
930 if (delta < 10 || (delta < 90 && targetIsClose(inst, -targetLabel))) {
931 int miStart = mi;
932 ForwardReference r = new ForwardReference.ShortBranch(mi, targetLabel);
933 forwardRefs = ForwardReference.enqueue(forwardRefs, r);
934 setMachineCodes(mi++, (byte) (0x70 + cond));
935 mi += 1; // leave space for displacement
936 if (lister != null) lister.I(miStart, "J" + CONDITION[cond], 0);
937 } else {
938 emitJCC_Cond_Label(cond, targetLabel);
939 }
940 }
941 }
942
943 /**
944 * Emit the given instruction, assuming that
945 * it is a MIR_Branch instruction
946 * and has a JMP operator
947 *
948 * @param inst the instruction to assemble
949 */
950 protected void doJMP(Instruction inst) {
951 if (isImm(MIR_Branch.getTarget(inst))) {
952 emitJMP_Imm(getImm(MIR_Branch.getTarget(inst)));
953 } else if (isLabel(MIR_Branch.getTarget(inst))) {
954 int sourceLabel = -inst.getmcOffset();
955 int targetLabel = getLabel(MIR_Branch.getTarget(inst));
956 int delta = targetLabel - sourceLabel;
957 if (VM.VerifyAssertions) VM._assert(delta >= 0);
958 if (delta < 10 || (delta < 90 && targetIsClose(inst, -targetLabel))) {
959 int miStart = mi;
960 ForwardReference r = new ForwardReference.ShortBranch(mi, targetLabel);
961 forwardRefs = ForwardReference.enqueue(forwardRefs, r);
962 setMachineCodes(mi++, (byte) 0xEB);
963 mi += 1; // leave space for displacement
964 if (lister != null) lister.I(miStart, "JMP", 0);
965 } else {
966 emitJMP_Label(getLabel(MIR_Branch.getTarget(inst)));
967 }
968 } else if (isReg(MIR_Branch.getTarget(inst))) {
969 emitJMP_Reg(getGPR_Reg(MIR_Branch.getTarget(inst)));
970 } else if (isAbs(MIR_Branch.getTarget(inst))) {
971 emitJMP_Abs(getDisp(MIR_Branch.getTarget(inst)).toWord().toAddress());
972 } else if (isRegDisp(MIR_Branch.getTarget(inst))) {
973 emitJMP_RegDisp(getBase(MIR_Branch.getTarget(inst)), getDisp(MIR_Branch.getTarget(inst)));
974 } else if (isRegOff(MIR_Branch.getTarget(inst))) {
975 emitJMP_RegOff(getIndex(MIR_Branch.getTarget(inst)),
976 getScale(MIR_Branch.getTarget(inst)),
977 getDisp(MIR_Branch.getTarget(inst)));
978 } else if (isRegIdx(MIR_Branch.getTarget(inst))) {
979 emitJMP_RegIdx(getBase(MIR_Branch.getTarget(inst)),
980 getIndex(MIR_Branch.getTarget(inst)),
981 getScale(MIR_Branch.getTarget(inst)),
982 getDisp(MIR_Branch.getTarget(inst)));
983 } else if (isRegInd(MIR_Branch.getTarget(inst))) {
984 emitJMP_RegInd(getBase(MIR_Branch.getTarget(inst)));
985 } else {
986 if (VM.VerifyAssertions) VM._assert(false, inst.toString());
987 }
988 }
989
990 /**
991 * Emit the given instruction, assuming that
992 * it is a MIR_LowTableSwitch instruction
993 * and has a MIR_LOWTABLESWITCH operator
994 *
995 * @param inst the instruction to assemble
996 */
997 protected void doLOWTABLESWITCH(Instruction inst) {
998 int n = MIR_LowTableSwitch.getNumberOfTargets(inst); // n = number of normal cases (0..n-1)
999 GPR ms = GPR.lookup(MIR_LowTableSwitch.getMethodStart(inst).getRegister().number);
1000 GPR idx = GPR.lookup(MIR_LowTableSwitch.getIndex(inst).getRegister().number);
1001 // idx += [ms + idx<<2 + ??] - we will patch ?? when we know the placement of the table
1002 int toPatchAddress = getMachineCodeIndex();
1003 if (VM.buildFor32Addr()) {
1004 emitMOV_Reg_RegIdx(idx, ms, idx, Assembler.WORD, Offset.fromIntZeroExtend(Integer.MAX_VALUE));
1005 emitADD_Reg_Reg(idx, ms);
1006 } else {
1007 emitMOV_Reg_RegIdx(idx, ms, idx, Assembler.WORD, Offset.fromIntZeroExtend(Integer.MAX_VALUE));
1008 emitADD_Reg_Reg_Quad(idx, ms);
1009 }
1010 // JMP T0
1011 emitJMP_Reg(idx);
1012 emitNOP((4-getMachineCodeIndex()) & 3); // align table
1013 // create table of offsets from start of method
1014 patchSwitchTableDisplacement(toPatchAddress);
1015 for (int i = 0; i < n; i++) {
1016 Operand target = MIR_LowTableSwitch.getTarget(inst, i);
1017 emitOFFSET_Imm_ImmOrLabel(i, getImm(target), getLabel(target));
1018 }
1019 }
1020
1021 /**
1022 * Debugging support (return a printable representation of the machine code).
1023 *
1024 * @param instr An integer to be interpreted as a PowerPC instruction
1025 * @param offset the mcoffset (in bytes) of the instruction
1026 */
1027 public String disasm(int instr, int offset) {
1028 OptimizingCompilerException.TODO("Assembler: disassembler");
1029 return null;
1030 }
1031
1032 /**
1033 * generate machine code into ir.machinecode.
1034 * @param ir the IR to generate
1035 * @param shouldPrint should we print the machine code?
1036 * @return the number of machinecode instructions generated
1037 */
1038 public static int generateCode(IR ir, boolean shouldPrint) {
1039 int count = 0;
1040 AssemblerOpt asm = new AssemblerOpt(count, shouldPrint, ir);
1041
1042 for (Instruction p = ir.firstInstructionInCodeOrder(); p != null; p = p.nextInstructionInCodeOrder()) {
1043 // Set the mc offset of all instructions to their negative position.
1044 // A positive value in their position means they have been created
1045 // by the assembler.
1046 count++;
1047 p.setmcOffset(-count);
1048 if (p.operator() == Operators.MIR_LOWTABLESWITCH) {
1049 // Table switch kludge, as these will occupy multiple slots in the
1050 // generated assembler
1051 count += MIR_LowTableSwitch.getNumberOfTargets(p);
1052 }
1053 }
1054
1055 for (Instruction p = ir.firstInstructionInCodeOrder(); p != null; p = p.nextInstructionInCodeOrder()) {
1056 if (DEBUG_ESTIMATE) {
1057 int start = asm.getMachineCodeIndex();
1058 int estimate = asm.estimateSize(p, start);
1059 asm.doInst(p);
1060 int end = asm.getMachineCodeIndex();
1061 if (end - start > estimate) {
1062 VM.sysWriteln("Bad estimate: " + (end - start) + " " + estimate + " " + p);
1063 VM.sysWrite("\tMachine code: ");
1064 asm.writeLastInstruction(start);
1065 VM.sysWriteln();
1066 }
1067 } else {
1068 asm.doInst(p);
1069 }
1070 }
1071
1072 ir.MIRInfo.machinecode = asm.getMachineCodes();
1073
1074 return ir.MIRInfo.machinecode.length();
1075 }
1076
1077 }