def handle_div(self, label, result, *operands): """Handles the div instruction of IR. """ restore_rax = True restore_rdx = True # This will be true only if the second operand is immediate. restore_r15 = False # Create dummy register objects for RAX and RDX and force color them to # ensure they take RAX and RDX values. So we can spill these two registers. # Also create memory object to where they get spilled. if self.is_register(result): if result.color == 0: restore_rax = False elif result.color == 3: restore_rdx = False # We may want %rax register to move the first dividend to %rax if it is # not already in %rax, so create a dummy %rax register in any case. rax = Register() rax.color = 0 # Color of RAX # We want to clear the contents of %rdx no matter what, so create a dummy # register for it. rdx = Register() rdx.color = 3 # Color of RDX # Store %rax and %rdx in memory if they have to be restored if restore_rax: rax.memory = Memory() rax_operands = (rax, rax.memory) self.handle_store(label, None, *rax_operands) if restore_rdx: rdx.memory = Memory() rdx_operands = (rdx, rdx.memory) self.handle_store(label, None, *rdx_operands) if not (self.is_register(operands[0]) and operands[0].color == 0): mov = MOV(rax, operands[0]) self.add_instruction(label, mov) # Clear %rdx, because x86_64 DIV instruction uses both %rax and %rdx as # the divisor xor = XOR(rdx, rdx) self.add_instruction(label, xor) if isinstance(operands[1], Immediate): # Create a dummy register object for %r15 for moving the operand to it. r15 = Register() r15.color = 13 if not(self.is_register(result) and result.color == 13): restore_r15 = True r15.memory = Memory() r15_operands = (r15, r15.memory) self.handle_store(label, None, *r15_operands) mov = MOV(r15, operands[1]) self.add_instruction(label, mov) idiv = IDIV(r15) else: idiv = IDIV(operands[1]) self.add_instruction(label, idiv) mov = MOV(result, rax) self.add_instruction(label, mov) if restore_rax: self.handle_load(label, rax, rax.memory) if restore_rdx: self.handle_load(label, rdx, rdx.memory) if restore_r15: self.handle_load(label, r15, r15.memory)