001 /*
002 * This file is part of the Jikes RVM project (http://jikesrvm.org).
003 *
004 * This file is licensed to You under the Common Public License (CPL);
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/cpl1.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 UNINT_BEGIN_opcode:
675 case UNINT_END_opcode: {
676 // these generate no code
677 return 0;
678 }
679 case IA32_METHODSTART_opcode:
680 return 12;
681 // Generated from the same case in Assembler
682 case IA32_ADC_opcode:
683 case IA32_ADD_opcode:
684 case IA32_AND_opcode:
685 case IA32_OR_opcode:
686 case IA32_SBB_opcode:
687 case IA32_XOR_opcode: {
688 int size = 2; // opcode + modr/m
689 size += operandCost(MIR_BinaryAcc.getResult(inst), true);
690 size += operandCost(MIR_BinaryAcc.getValue(inst), true);
691 return size;
692 }
693 case IA32_CMP_opcode: {
694 int size = 2; // opcode + modr/m
695 size += operandCost(MIR_Compare.getVal1(inst), true);
696 size += operandCost(MIR_Compare.getVal2(inst), true);
697 return size;
698 }
699 case IA32_TEST_opcode: {
700 int size = 2; // opcode + modr/m
701 size += operandCost(MIR_Test.getVal1(inst), false);
702 size += operandCost(MIR_Test.getVal2(inst), false);
703 return size;
704 }
705 case IA32_ADDSD_opcode:
706 case IA32_SUBSD_opcode:
707 case IA32_MULSD_opcode:
708 case IA32_DIVSD_opcode:
709 case IA32_XORPD_opcode:
710 case IA32_SQRTSD_opcode:
711 case IA32_ADDSS_opcode:
712 case IA32_SUBSS_opcode:
713 case IA32_MULSS_opcode:
714 case IA32_DIVSS_opcode:
715 case IA32_XORPS_opcode: {
716 int size = 4; // opcode + modr/m
717 Operand value = MIR_BinaryAcc.getValue(inst);
718 size += operandCost(value, false);
719 return size;
720 }
721 case IA32_UCOMISS_opcode: {
722 int size = 3; // opcode + modr/m
723 Operand val2 = MIR_Compare.getVal2(inst);
724 size += operandCost(val2, false);
725 return size;
726 }
727 case IA32_UCOMISD_opcode: {
728 int size = 4; // opcode + modr/m
729 Operand val2 = MIR_Compare.getVal2(inst);
730 size += operandCost(val2, false);
731 return size;
732 }
733 case IA32_CVTSI2SS_opcode:
734 case IA32_CVTSI2SD_opcode:
735 case IA32_CVTSS2SD_opcode:
736 case IA32_CVTSD2SS_opcode:
737 case IA32_CVTSD2SI_opcode:
738 case IA32_CVTTSD2SI_opcode:
739 case IA32_CVTSS2SI_opcode:
740 case IA32_CVTTSS2SI_opcode: {
741 int size = 4; // opcode + modr/m
742 Operand result = MIR_Unary.getResult(inst);
743 Operand value = MIR_Unary.getVal(inst);
744 size += operandCost(result, false);
745 size += operandCost(value, false);
746 return size;
747 }
748 case IA32_CMPEQSD_opcode:
749 case IA32_CMPLTSD_opcode:
750 case IA32_CMPLESD_opcode:
751 case IA32_CMPUNORDSD_opcode:
752 case IA32_CMPNESD_opcode:
753 case IA32_CMPNLTSD_opcode:
754 case IA32_CMPNLESD_opcode:
755 case IA32_CMPORDSD_opcode:
756 case IA32_CMPEQSS_opcode:
757 case IA32_CMPLTSS_opcode:
758 case IA32_CMPLESS_opcode:
759 case IA32_CMPUNORDSS_opcode:
760 case IA32_CMPNESS_opcode:
761 case IA32_CMPNLTSS_opcode:
762 case IA32_CMPNLESS_opcode:
763 case IA32_CMPORDSS_opcode: {
764 int size = 5; // opcode + modr/m + type
765 Operand value = MIR_BinaryAcc.getValue(inst);
766 size += operandCost(value, false);
767 return size;
768 }
769 case IA32_MOVD_opcode:
770 case IA32_MOVLPD_opcode:
771 case IA32_MOVQ_opcode:
772 case IA32_MOVSS_opcode:
773 case IA32_MOVSD_opcode: {
774 int size = 4; // opcode + modr/m
775 Operand result = MIR_Move.getResult(inst);
776 Operand value = MIR_Move.getValue(inst);
777 size += operandCost(result, false);
778 size += operandCost(value, false);
779 return size;
780 }
781 case IA32_PUSH_opcode: {
782 Operand op = MIR_UnaryNoRes.getVal(inst);
783 int size = 0;
784 if (op instanceof RegisterOperand) {
785 size += 1;
786 } else if (op instanceof IntConstantOperand) {
787 if (fits(((IntConstantOperand) op).value, 8)) {
788 size += 2;
789 } else {
790 size += 5;
791 }
792 } else {
793 size += (2 + operandCost(op, true));
794 }
795 return size;
796 }
797 case IA32_LEA_opcode: {
798 int size = 2; // opcode + 1 byte modr/m
799 size += operandCost(MIR_Lea.getResult(inst), false);
800 size += operandCost(MIR_Lea.getValue(inst), false);
801 return size;
802 }
803 case IA32_MOV_opcode: {
804 int size = 2; // opcode + modr/m
805 Operand result = MIR_Move.getResult(inst);
806 Operand value = MIR_Move.getValue(inst);
807 size += operandCost(result, false);
808 size += operandCost(value, false);
809 return size;
810 }
811 case MIR_LOWTABLESWITCH_opcode:
812 return MIR_LowTableSwitch.getNumberOfTargets(inst)*4 + 14;
813 case IA32_OFFSET_opcode:
814 return 4;
815 case IA32_JCC_opcode:
816 case IA32_JMP_opcode:
817 return 6; // assume long form
818 case IA32_LOCK_opcode:
819 return 1;
820 case IG_PATCH_POINT_opcode:
821 return 8;
822 case IA32_INT_opcode:
823 return 2;
824 case IA32_RET_opcode:
825 return 3;
826 case IA32_CALL_opcode:
827 Operand target = MIR_Call.getTarget(inst);
828 if (isImmOrLabel(target)) {
829 return 5; // opcode + 32bit immediate
830 } else {
831 return 2 + operandCost(target, false); // opcode + modr/m
832 }
833 default: {
834 int size = 3; // 2 bytes opcode + 1 byte modr/m
835 for (OperandEnumeration opEnum = inst.getRootOperands(); opEnum.hasMoreElements();) {
836 Operand op = opEnum.next();
837 size += operandCost(op, false);
838 }
839 return size;
840 }
841 }
842 }
843
844 private int operandCost(Operand op, boolean shortFormImmediate) {
845 if (op instanceof MemoryOperand) {
846 MemoryOperand mop = (MemoryOperand) op;
847 // If it's a 2byte mem location, we're going to need an override prefix
848 int prefix = mop.size == 2 ? 1 : 0;
849
850 // Deal with EBP wierdness
851 if (mop.base != null && mop.base.getRegister() == EBP) {
852 if (mop.index != null) {
853 // forced into SIB + 32 bit displacement no matter what disp is
854 return prefix + 5;
855 }
856 if (fits(mop.disp, 8)) {
857 return prefix + 1;
858 } else {
859 return prefix + 4;
860 }
861 }
862 if (mop.index != null && mop.index.getRegister() == EBP) {
863 // forced into SIB + 32 bit displacement no matter what disp is
864 return prefix + 5;
865 }
866
867 // Deal with ESP wierdness -- requires SIB byte even when index is null
868 if (mop.base != null && mop.base.getRegister() == ESP) {
869 if (fits(mop.disp, 8)) {
870 return prefix + 2;
871 } else {
872 return prefix + 5;
873 }
874 }
875
876 if (mop.index == null) {
877 // just displacement to worry about
878 if (mop.disp.isZero()) {
879 return prefix + 0;
880 } else if (fits(mop.disp, 8)) {
881 return prefix + 1;
882 } else {
883 return prefix + 4;
884 }
885 } else {
886 // have a SIB
887 if (mop.base == null && mop.scale != 0) {
888 // forced to 32 bit displacement even if it would fit in 8
889 return prefix + 5;
890 } else {
891 if (mop.disp.isZero()) {
892 return prefix + 1;
893 } else if (fits(mop.disp, 8)) {
894 return prefix + 2;
895 } else {
896 return prefix + 5;
897 }
898 }
899 }
900 } else if (op instanceof IntConstantOperand) {
901 if (shortFormImmediate && fits(((IntConstantOperand) op).value, 8)) {
902 return 1;
903 } else {
904 return 4;
905 }
906 } else {
907 return 0;
908 }
909 }
910
911 /**
912 * Emit the given instruction, assuming that
913 * it is a MIR_CondBranch instruction
914 * and has a JCC operator
915 *
916 * @param inst the instruction to assemble
917 */
918 protected void doJCC(Instruction inst) {
919 byte cond = getCond(MIR_CondBranch.getCond(inst));
920 if (isImm(MIR_CondBranch.getTarget(inst))) {
921 emitJCC_Cond_Imm(cond, getImm(MIR_CondBranch.getTarget(inst)));
922 } else {
923 if (VM.VerifyAssertions && !isLabel(MIR_CondBranch.getTarget(inst))) VM._assert(false, inst.toString());
924 int sourceLabel = -inst.getmcOffset();
925 int targetLabel = getLabel(MIR_CondBranch.getTarget(inst));
926 int delta = targetLabel - sourceLabel;
927 if (VM.VerifyAssertions) VM._assert(delta >= 0);
928 if (delta < 10 || (delta < 90 && targetIsClose(inst, -targetLabel))) {
929 int miStart = mi;
930 ForwardReference r = new ForwardReference.ShortBranch(mi, targetLabel);
931 forwardRefs = ForwardReference.enqueue(forwardRefs, r);
932 setMachineCodes(mi++, (byte) (0x70 + cond));
933 mi += 1; // leave space for displacement
934 if (lister != null) lister.I(miStart, "J" + CONDITION[cond], 0);
935 } else {
936 emitJCC_Cond_Label(cond, targetLabel);
937 }
938 }
939 }
940
941 /**
942 * Emit the given instruction, assuming that
943 * it is a MIR_Branch instruction
944 * and has a JMP operator
945 *
946 * @param inst the instruction to assemble
947 */
948 protected void doJMP(Instruction inst) {
949 if (isImm(MIR_Branch.getTarget(inst))) {
950 emitJMP_Imm(getImm(MIR_Branch.getTarget(inst)));
951 } else if (isLabel(MIR_Branch.getTarget(inst))) {
952 int sourceLabel = -inst.getmcOffset();
953 int targetLabel = getLabel(MIR_Branch.getTarget(inst));
954 int delta = targetLabel - sourceLabel;
955 if (VM.VerifyAssertions) VM._assert(delta >= 0);
956 if (delta < 10 || (delta < 90 && targetIsClose(inst, -targetLabel))) {
957 int miStart = mi;
958 ForwardReference r = new ForwardReference.ShortBranch(mi, targetLabel);
959 forwardRefs = ForwardReference.enqueue(forwardRefs, r);
960 setMachineCodes(mi++, (byte) 0xEB);
961 mi += 1; // leave space for displacement
962 if (lister != null) lister.I(miStart, "JMP", 0);
963 } else {
964 emitJMP_Label(getLabel(MIR_Branch.getTarget(inst)));
965 }
966 } else if (isReg(MIR_Branch.getTarget(inst))) {
967 emitJMP_Reg(getGPR_Reg(MIR_Branch.getTarget(inst)));
968 } else if (isAbs(MIR_Branch.getTarget(inst))) {
969 emitJMP_Abs(getDisp(MIR_Branch.getTarget(inst)).toWord().toAddress());
970 } else if (isRegDisp(MIR_Branch.getTarget(inst))) {
971 emitJMP_RegDisp(getBase(MIR_Branch.getTarget(inst)), getDisp(MIR_Branch.getTarget(inst)));
972 } else if (isRegOff(MIR_Branch.getTarget(inst))) {
973 emitJMP_RegOff(getIndex(MIR_Branch.getTarget(inst)),
974 getScale(MIR_Branch.getTarget(inst)),
975 getDisp(MIR_Branch.getTarget(inst)));
976 } else if (isRegIdx(MIR_Branch.getTarget(inst))) {
977 emitJMP_RegIdx(getBase(MIR_Branch.getTarget(inst)),
978 getIndex(MIR_Branch.getTarget(inst)),
979 getScale(MIR_Branch.getTarget(inst)),
980 getDisp(MIR_Branch.getTarget(inst)));
981 } else if (isRegInd(MIR_Branch.getTarget(inst))) {
982 emitJMP_RegInd(getBase(MIR_Branch.getTarget(inst)));
983 } else {
984 if (VM.VerifyAssertions) VM._assert(false, inst.toString());
985 }
986 }
987
988 /**
989 * Emit the given instruction, assuming that
990 * it is a MIR_LowTableSwitch instruction
991 * and has a MIR_LOWTABLESWITCH operator
992 *
993 * @param inst the instruction to assemble
994 */
995 protected void doLOWTABLESWITCH(Instruction inst) {
996 int n = MIR_LowTableSwitch.getNumberOfTargets(inst); // n = number of normal cases (0..n-1)
997 GPR ms = GPR.lookup(MIR_LowTableSwitch.getMethodStart(inst).getRegister().number);
998 GPR idx = GPR.lookup(MIR_LowTableSwitch.getIndex(inst).getRegister().number);
999 // idx += [ms + idx<<2 + ??] - we will patch ?? when we know the placement of the table
1000 int toPatchAddress = getMachineCodeIndex();
1001 if (VM.buildFor32Addr()) {
1002 emitMOV_Reg_RegIdx(idx, ms, idx, Assembler.WORD, Offset.fromIntZeroExtend(Integer.MAX_VALUE));
1003 emitADD_Reg_Reg(idx, ms);
1004 } else {
1005 emitMOV_Reg_RegIdx(idx, ms, idx, Assembler.WORD, Offset.fromIntZeroExtend(Integer.MAX_VALUE));
1006 emitADD_Reg_Reg_Quad(idx, ms);
1007 }
1008 // JMP T0
1009 emitJMP_Reg(idx);
1010 emitNOP((4-getMachineCodeIndex()) & 3); // align table
1011 // create table of offsets from start of method
1012 patchSwitchTableDisplacement(toPatchAddress);
1013 for (int i = 0; i < n; i++) {
1014 Operand target = MIR_LowTableSwitch.getTarget(inst, i);
1015 emitOFFSET_Imm_ImmOrLabel(i, getImm(target), getLabel(target));
1016 }
1017 }
1018
1019 /**
1020 * Debugging support (return a printable representation of the machine code).
1021 *
1022 * @param instr An integer to be interpreted as a PowerPC instruction
1023 * @param offset the mcoffset (in bytes) of the instruction
1024 */
1025 public String disasm(int instr, int offset) {
1026 OptimizingCompilerException.TODO("Assembler: disassembler");
1027 return null;
1028 }
1029
1030 /**
1031 * generate machine code into ir.machinecode.
1032 * @param ir the IR to generate
1033 * @param shouldPrint should we print the machine code?
1034 * @return the number of machinecode instructions generated
1035 */
1036 public static int generateCode(IR ir, boolean shouldPrint) {
1037 int count = 0;
1038 AssemblerOpt asm = new AssemblerOpt(count, shouldPrint, ir);
1039
1040 for (Instruction p = ir.firstInstructionInCodeOrder(); p != null; p = p.nextInstructionInCodeOrder()) {
1041 // Set the mc offset of all instructions to their negative position.
1042 // A positive value in their position means they have been created
1043 // by the assembler.
1044 count++;
1045 p.setmcOffset(-count);
1046 if (p.operator() == Operators.MIR_LOWTABLESWITCH) {
1047 // Table switch kludge, as these will occupy multiple slots in the
1048 // generated assembler
1049 count += MIR_LowTableSwitch.getNumberOfTargets(p);
1050 }
1051 }
1052
1053 for (Instruction p = ir.firstInstructionInCodeOrder(); p != null; p = p.nextInstructionInCodeOrder()) {
1054 if (DEBUG_ESTIMATE) {
1055 int start = asm.getMachineCodeIndex();
1056 int estimate = asm.estimateSize(p, start);
1057 asm.doInst(p);
1058 int end = asm.getMachineCodeIndex();
1059 if (end - start > estimate) {
1060 VM.sysWriteln("Bad estimate: " + (end - start) + " " + estimate + " " + p);
1061 VM.sysWrite("\tMachine code: ");
1062 asm.writeLastInstruction(start);
1063 VM.sysWriteln();
1064 }
1065 } else {
1066 asm.doInst(p);
1067 }
1068 }
1069
1070 ir.MIRInfo.machinecode = asm.getMachineCodes();
1071
1072 return ir.MIRInfo.machinecode.length();
1073 }
1074
1075 }