< prev index next >

src/cpu/aarch32/vm/assembler_aarch32.cpp

Print this page
rev 8069 : 8164652: aarch32: C1 port


1358   assert( _wb_mode != pre && _wb_mode != post, "Wrong wb mode");
1359   // could probably permit post however
1360   switch(_acc_mode) {
1361   case imm: {
1362     if (_offset == 0 && _base == r) // it's a nop
1363       break;
1364     if (_offset > 0)
1365       __ add(r, _base, _offset);
1366     else
1367       __ sub(r, _base, -_offset);
1368       break;
1369   }
1370   case reg: {
1371     __ add(r, _base, _index, _shift);
1372     break;
1373   }
1374   case lit: {
1375     if (rtype == relocInfo::none)
1376       __ mov(r, target());
1377     else
1378       __ movptr(r, (u_int32_t)target());
1379     break;
1380   }
1381   default:
1382     ShouldNotReachHere();
1383   }
1384 }
1385 #undef __
1386 
1387 #define __ as->
1388 class Address;
1389 
1390 // Adapts given Address to the capabilities of instructions respective to the
1391 // provided data type. E.g. some of the instructions cannot use index register
1392 // while others cannot have an offset field.
1393 // Returns a copy of this Address is it's good or constructs a new Address
1394 // good for respective instructions by emitting necessary code to calculate
1395 // the address in tmp register
1396 Address Address::safe_for(InsnDataType type, MacroAssembler *as, Register tmp) {
1397   if (is_safe_for(type))
1398     return *this;


1676   if(is_valid_for_imm12(imm32)) {
1677     if(s) movs_i(dst, (unsigned)imm32, cond);
1678     else  mov_i (dst, (unsigned)imm32, cond);
1679   } else if(is_valid_for_imm12(~imm32)) {
1680     if(s) mvns_i(dst, (unsigned)~imm32, cond);
1681     else  mvn_i (dst, (unsigned)~imm32, cond);
1682   } else if (!s && VM_Version::features() & (FT_ARMV7 | FT_ARMV6T2) &&
1683              (imm32 < (1 << 16))) {
1684     movw_i(dst, (unsigned)imm32, cond);
1685   } else if (!s && VM_Version::features() & (FT_ARMV7 | FT_ARMV6T2) &&
1686              !(imm32 & ((1 << 16) - 1))) {
1687     movw_i(dst, (unsigned)0, cond);
1688     movt_i(dst, (unsigned)(imm32 >> 16), cond);
1689   } else { // TODO Could expand to varied numbers of mov and orrs
1690     //Need to do a full 32 bits
1691     mov_immediate32(dst, imm32, cond, s);
1692   }
1693 }
1694 
1695 //This should really be in the macroassembler
1696 void Assembler::mov_immediate32(Register dst, u_int32_t imm32, Condition cond, bool s)
1697 {
1698   // Need to move a full 32 bit immediate, for example if we're loading an address that
1699   // might change later and therefore need to be updated.
1700   if (VM_Version::features() & (FT_ARMV7 | FT_ARMV6T2))  {
1701     //Use a movw and a movt
1702     Assembler::movw_i(dst, (unsigned)(imm32 & 0xffff), cond);
1703     Assembler::movt_i(dst, (unsigned)(imm32 >> 16), cond);
1704     if(s) {
1705       //Additionally emit a cmp instruction
1706       Assembler::cmp(dst, 0);
1707     }
1708   } else {
1709     // Sadly we don't have movw, movt
1710     // instead emit a mov and three orr
1711     mov_i(dst,    imm32 & (0xff      ), cond);
1712     orr(dst, dst, imm32 & (0xff << 8 ), cond);
1713     orr(dst, dst, imm32 & (0xff << 16), cond);
1714     if(s) orrs(dst, dst, imm32 & (0xff << 24), cond);
1715     else  orr (dst, dst, imm32 & (0xff << 24), cond);
1716   }


1718 
1719 #define starti Instruction_aarch32 do_not_use(this); set_current(&do_not_use)
1720 void Assembler::add_sub_imm(int decode, Register Rd, Register Rn, int imm,
1721                             Condition cond, bool s) {
1722   int cpart = 0;
1723   switch(decode) {
1724     case 0b0100: cpart = 0b0010; break; // ADD  ->  SUB
1725     case 0b0010:                        // SUB  ->  ADD
1726     case 0b0011: cpart = 0b0100; break; // RSB  ->  ADD
1727     case 0b0101: cpart = 0b0110; break; // ADC  ->  SUBC
1728     case 0b0110:                        // SUBC ->  ADC
1729     case 0b0111: cpart = 0b0101; break; // RSC  ->  ADC
1730     default: ShouldNotReachHere();
1731   }
1732   //try both possible imm_instrs
1733   if(imm_instr(decode, Rd, Rn, imm, cond, s)) return;
1734   if(imm_instr(cpart, Rd, Rn, -imm, cond, s)) return;
1735 
1736   //Try plan B - a mov first - need to have destination that is not an arg
1737   assert(Rd != Rn, "Can't use imm and can't do a mov. I'm in a jam.");
1738   mov_immediate(Rd, (u_int32_t)uabs(imm), cond, s);
1739   //Now do the non immediate version - copied from the immediate encodings
1740   {
1741     starti;
1742     reg_instr( imm < 0 ? cpart : decode, lsl(), cond, s);
1743     rf(Rn, 16), rf(Rd, 12), rf(Rd, 0);
1744   }
1745 }
1746 
1747 void Assembler::vmov_imm(FloatRegister Rd, unsigned imm, bool is64bit,
1748                          Condition cond) {
1749   starti;
1750   fp_instr_base(is64bit, cond);
1751   f(0b1011, 23, 20);
1752   // double register passed (see 'd0'-'dN' encoding), not reencode it's number
1753   fp_rencode(Rd, false, 12, 22);
1754   f(0b0000, 7, 4);
1755   f(imm & 0xf, 3, 0);
1756   f(imm >> 4, 19, 16);
1757 }
1758 




1358   assert( _wb_mode != pre && _wb_mode != post, "Wrong wb mode");
1359   // could probably permit post however
1360   switch(_acc_mode) {
1361   case imm: {
1362     if (_offset == 0 && _base == r) // it's a nop
1363       break;
1364     if (_offset > 0)
1365       __ add(r, _base, _offset);
1366     else
1367       __ sub(r, _base, -_offset);
1368       break;
1369   }
1370   case reg: {
1371     __ add(r, _base, _index, _shift);
1372     break;
1373   }
1374   case lit: {
1375     if (rtype == relocInfo::none)
1376       __ mov(r, target());
1377     else
1378       __ movptr(r, (uint32_t)target());
1379     break;
1380   }
1381   default:
1382     ShouldNotReachHere();
1383   }
1384 }
1385 #undef __
1386 
1387 #define __ as->
1388 class Address;
1389 
1390 // Adapts given Address to the capabilities of instructions respective to the
1391 // provided data type. E.g. some of the instructions cannot use index register
1392 // while others cannot have an offset field.
1393 // Returns a copy of this Address is it's good or constructs a new Address
1394 // good for respective instructions by emitting necessary code to calculate
1395 // the address in tmp register
1396 Address Address::safe_for(InsnDataType type, MacroAssembler *as, Register tmp) {
1397   if (is_safe_for(type))
1398     return *this;


1676   if(is_valid_for_imm12(imm32)) {
1677     if(s) movs_i(dst, (unsigned)imm32, cond);
1678     else  mov_i (dst, (unsigned)imm32, cond);
1679   } else if(is_valid_for_imm12(~imm32)) {
1680     if(s) mvns_i(dst, (unsigned)~imm32, cond);
1681     else  mvn_i (dst, (unsigned)~imm32, cond);
1682   } else if (!s && VM_Version::features() & (FT_ARMV7 | FT_ARMV6T2) &&
1683              (imm32 < (1 << 16))) {
1684     movw_i(dst, (unsigned)imm32, cond);
1685   } else if (!s && VM_Version::features() & (FT_ARMV7 | FT_ARMV6T2) &&
1686              !(imm32 & ((1 << 16) - 1))) {
1687     movw_i(dst, (unsigned)0, cond);
1688     movt_i(dst, (unsigned)(imm32 >> 16), cond);
1689   } else { // TODO Could expand to varied numbers of mov and orrs
1690     //Need to do a full 32 bits
1691     mov_immediate32(dst, imm32, cond, s);
1692   }
1693 }
1694 
1695 //This should really be in the macroassembler
1696 void Assembler::mov_immediate32(Register dst, uint32_t imm32, Condition cond, bool s)
1697 {
1698     // Need to move a full 32 bit immediate, for example if we're loading an address that
1699     // might change later and therefore need to be updated.
1700   if (VM_Version::features() & (FT_ARMV7 | FT_ARMV6T2))  {
1701     //Use a movw and a movt
1702     Assembler::movw_i(dst, (unsigned)(imm32 & 0xffff), cond);
1703     Assembler::movt_i(dst, (unsigned)(imm32 >> 16), cond);
1704     if(s) {
1705       //Additionally emit a cmp instruction
1706       Assembler::cmp(dst, 0);
1707     }
1708   } else {
1709     // Sadly we don't have movw, movt
1710     // instead emit a mov and three orr
1711     mov_i(dst,    imm32 & (0xff      ), cond);
1712     orr(dst, dst, imm32 & (0xff << 8 ), cond);
1713     orr(dst, dst, imm32 & (0xff << 16), cond);
1714     if(s) orrs(dst, dst, imm32 & (0xff << 24), cond);
1715     else  orr (dst, dst, imm32 & (0xff << 24), cond);
1716   }


1718 
1719 #define starti Instruction_aarch32 do_not_use(this); set_current(&do_not_use)
1720 void Assembler::add_sub_imm(int decode, Register Rd, Register Rn, int imm,
1721                             Condition cond, bool s) {
1722   int cpart = 0;
1723   switch(decode) {
1724     case 0b0100: cpart = 0b0010; break; // ADD  ->  SUB
1725     case 0b0010:                        // SUB  ->  ADD
1726     case 0b0011: cpart = 0b0100; break; // RSB  ->  ADD
1727     case 0b0101: cpart = 0b0110; break; // ADC  ->  SUBC
1728     case 0b0110:                        // SUBC ->  ADC
1729     case 0b0111: cpart = 0b0101; break; // RSC  ->  ADC
1730     default: ShouldNotReachHere();
1731   }
1732   //try both possible imm_instrs
1733   if(imm_instr(decode, Rd, Rn, imm, cond, s)) return;
1734   if(imm_instr(cpart, Rd, Rn, -imm, cond, s)) return;
1735 
1736   //Try plan B - a mov first - need to have destination that is not an arg
1737   assert(Rd != Rn, "Can't use imm and can't do a mov. I'm in a jam.");
1738   mov_immediate(Rd, (uint32_t)uabs(imm), cond, s);
1739   //Now do the non immediate version - copied from the immediate encodings
1740   {
1741     starti;
1742     reg_instr( imm < 0 ? cpart : decode, lsl(), cond, s);
1743     rf(Rn, 16), rf(Rd, 12), rf(Rd, 0);
1744   }
1745 }
1746 
1747 void Assembler::vmov_imm(FloatRegister Rd, unsigned imm, bool is64bit,
1748                          Condition cond) {
1749   starti;
1750   fp_instr_base(is64bit, cond);
1751   f(0b1011, 23, 20);
1752   // double register passed (see 'd0'-'dN' encoding), not reencode it's number
1753   fp_rencode(Rd, false, 12, 22);
1754   f(0b0000, 7, 4);
1755   f(imm & 0xf, 3, 0);
1756   f(imm >> 4, 19, 16);
1757 }
1758 


< prev index next >